home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin / F2JW / trans / verb.cpp < prev   
C/C++ Source or Header  |  2000-01-18  |  63KB  |  2,173 lines

  1. //
  2. // フランス語 → 日本語 翻訳プログラム
  3. //
  4. // 主に動詞に関わるところ
  5.  
  6. #include "stdafx.h"
  7. #include    <ctype.h>
  8.  
  9. #include    "f2j.h"
  10. #include    "score.h"
  11. #include    "myprot.h"
  12.  
  13. extern    TOKEN        *currentTree;
  14. extern    ADVERB        dic_adverb_NE;
  15. extern    PRONOUN        dic_indicationg_noun;
  16. extern    PRONOUN        nullPronoun;
  17. extern    BOOL        isChanged;
  18.  
  19.  
  20. //
  21. // 補語人称代名詞を処理
  22. //
  23. void
  24. ProcessObjectPronoun(TOKEN *start)
  25. {
  26.     TOKEN    *p = start->next;
  27.  
  28.     if(p == NULL)    return;
  29.  
  30.     // le voila
  31.     if(p->frPart == FR_PART_ARTICLE_PRONOUN
  32.     && p->next
  33.     && (p->next->frPart & FR_PART_VERB)
  34.     && ((VERB *)p->next->what)->frVerbKind == 0
  35.     && currentTree->punctuation != FR_PUNCT_QUESTION) {
  36.         TOKEN    *o2 = p,    *v = p->next;
  37.         SetVerbPronounObject(start, v, v, o2, NULL, NULL, NULL);
  38.         if(isChanged)    return;
  39.     }
  40.  
  41.     if(currentTree->punctuation == FR_PUNCT_QUESTION
  42.     || p->what == &dic_adverb_NE)    {    // 否定命令文
  43.         ProcessObjectPronoun_Normal(start);
  44.     } else if((p->frPart & FR_PART_VERB)
  45.         &&     !(p->frTense & (FR_TENSE)(FR_TENSE_P_PAST | FR_TENSE_P_PRESENT))) {
  46.         // 分詞構文では、命令文でないが、動詞が先頭に来る
  47.         ProcessObjectPronoun_Order(start);
  48.         // 動詞目的語を伴う命令形? eg) allez vous laver les mains.
  49.         if(isChanged == FALSE)
  50.             ProcessObjectPronoun_Normal(start->next);
  51.     } else {
  52.         // 最初の1語は飛ばす vous vous levez -> levez-vous-vous とならないように
  53.         ProcessObjectPronoun_Normal(start);
  54.     }
  55. }
  56.  
  57.  
  58. void
  59. ProcessObjectPronoun_Normal(TOKEN *start)
  60. {
  61.     TOKEN    *prev = start;
  62.     TOKEN    *p = prev->next;
  63.  
  64.     while(p && p->next) {
  65.         TOKEN    *verb = p->next;
  66.  
  67.         if((verb->frPart & FR_PART_VERB)
  68.         &&  verb->which == NULL
  69.         &&  verb->moved < 2) {
  70.             if(p->frPart == FR_PART_SPECIAL_EN)
  71.                 SwapPronounVerb(start, p, verb);
  72.             else if(p->frPart == FR_PART_SPECIAL_SE)
  73.                 SwapPronounVerb(start, p, verb);
  74.             else if(p->frPart == FR_PART_ADVERB_Y)
  75.                 SwapPronounVerb(start, p, verb);
  76.             else if(p->frPart == FR_PART_ARTICLE_PRONOUN)    // le, la, les
  77.                 SwapPronounVerb(start, p, verb);
  78.             else if(IsObjectMatch(p, FR_PART_NOUN_OBJECT_BOTH)) {
  79.                 if(IsObjectMatch(p, FR_PART_NOUN_SUBJECT))    // nous か vous
  80.                     DeterminNousVous(prev, p, verb);
  81.                 if(IsObjectMatch(p, FR_PART_NOUN_OBJECT_BOTH))    // DeterminNousVousで、FR_PART_NOUN_SUBJECTにされているかもしれないので、
  82.                     SwapPronounVerb(start, p, verb);
  83.             }
  84.         }
  85.         prev = p;
  86.         p = p->next;
  87.     }
  88. }
  89.  
  90. //
  91. // <Nous>と<Vous>を見極める (主語か目的代名詞か)
  92. //
  93. void
  94. DeterminNousVous(TOKEN *prev, TOKEN *p, TOKEN *verb)
  95. {
  96.     if(prev->frPart == FR_PART_NONE                    // 行頭
  97.     || IsObjectMatch(prev, FR_PART_SENTENCE_ALL)    // si vous voulez -> si voulez-vousとならないように
  98.     || prev->frPart == FR_PART_RELATIVE_OBJECT) {    // la montre que <vous> achetez.
  99.         if((verb->frTense & FR_TENSE_ORIGIN)        // Vous avoir rencontr{ est plasir.
  100.         || (verb->frTense & FR_TENSE_P_PRESENT)        // Vous <voyant> agir ainsi, elle sera f[ch{e.
  101.         || (verb->punctuation == FR_PUNCT_HYPHEN))    // <Vous> levez-vous?
  102.             goto TwoChoice;
  103.         p->frPart = FR_PART_NOUN_SUBJECT;
  104.         return;
  105.     } else if(prev->frPart == FR_PART_NOUN_SUBJECT
  106.     || prev->frPart == FR_PART_RELATIVE_SUBJECT
  107. //    || IsObjectMatch(prev, FR_PART_NOUN_GENERAL)
  108. //    || IsObjectMatch(prev, FR_PART_NOUN_OBJECT_BOTH)
  109.     || p->frPart == FR_PART_ARTICLE_PRONOUN    // le, la, les
  110.     || p->frPart == FR_PART_ADVERB_Y
  111.     || p->what == &dic_adverb_NE) {
  112.         p->frPart = FR_PART_NOUN_OBJECT_BOTH;
  113.         return;
  114.     }
  115. TwoChoice:
  116.     TOKEN    *altP = CopyCurrentTree(p, "DeterminNousVous");
  117.     p->frPart = FR_PART_NOUN_OBJECT_BOTH;
  118.     altP->frPart = FR_PART_NOUN_SUBJECT;
  119. }
  120.  
  121. //
  122. // 補語人称代名詞と動詞を代える
  123. //
  124. void
  125. SwapPronounVerb(TOKEN *start, TOKEN *p, TOKEN *verb)
  126. {
  127.     BOOL    noChoice = FALSE;    // 必ず補語人称代名詞か? (vous, nous)
  128.  
  129.     if(p->moved > 0)    return;    // すでに移動済み
  130.  
  131. //    DisconnectTOKEN(start, p);
  132.     if((verb->punctuation & FR_PUNCT_HYPHEN)
  133.     && verb->next
  134.     && IsObjectMatch(verb->next, FR_PART_NOUN_SUBJECT)) {    // 疑問文など vous levez-vous?
  135. //        SwapVerbSubject(verb, verb->next);
  136.         MustBeSubject(verb->next);
  137.         verb = verb->next;
  138.         verb->jpProp |= JP_PROP_QUESTION;
  139.     }
  140.  
  141.     if(IsTokenFrench(verb, "]tre"))    {
  142.         TOKEN    *nextVerb = verb->next;
  143.         while(nextVerb && (nextVerb->frPart & FR_PART_ADVERB))    // Elles se sont <souvent> {crite.
  144.             nextVerb = nextVerb->next;
  145.         if( nextVerb
  146.         && (nextVerb->frPart & FR_PART_VERB)
  147.         && (nextVerb->frTense == FR_TENSE_PASSIVE)) {
  148.             // Je me suis lev{. -> 受動態の候補 eg) etre lev{ 
  149.             // <je suis me> + <lev{> の分詞構文ではない
  150.             nextVerb->frPartChoice = (FR_PART)(nextVerb->frPartChoice & ~FR_PART_INDEPENDENCE);
  151.             // 複合過去はすでに処理されている
  152.             verb->moved++;
  153.             verb = nextVerb;    // 視点を受動態の動詞に移す eg) il vous est donn{.
  154.         }
  155.     }
  156.     if(p->frPart == FR_PART_SPECIAL_EN) {    // il y en a deux -> il a y <en deux>.のために最初に行う
  157.         ChangeToObjectPronoun(p, "en");
  158.         p->frPart = FR_PART_NOUN_OBJECT_D;    // (FR_PART)(FR_PART_NOUN_OBJECT_D | FR_PART_NOUN_OBJECT_I);
  159.     } else if(p->frPart == FR_PART_SPECIAL_SE) {
  160.         ChangeToPronoun(p, "se");
  161.     } else if(p->frPart == FR_PART_ARTICLE_PRONOUN) {
  162.         ChangeToObjectPronoun(p, GetTokenFrench(p));
  163.     }
  164.  
  165.     if(IsAttribMatch(verb, p)) {
  166.         p->frPart = (FR_PART)(p->frPart | FR_PART_NOUN_RECURSIVE);
  167.     }
  168.     InsertObjectPronounAfterVerb(start, verb, p);
  169. }
  170.  
  171. //
  172. // 動詞の後に人称格代名詞を入れる
  173. //
  174. void
  175. InsertObjectPronounAfterVerb(TOKEN *start, TOKEN *verb, TOKEN *p)
  176. {
  177.     char    word[10];
  178.     FR_PART    frPart;
  179.     TOKEN    *q;
  180.  
  181.     strcpy(word, GetTokenFrench(p));
  182.     DisconnectTOKEN(start, p);
  183.     p->moved = TRUE;    // 処理済み
  184.  
  185.     if(IsTokenFrench(p, "en")) {
  186.         frPart = (FR_PART)(FR_PART_ADJECTIVE | FR_PART_NOUN);
  187.     } else {
  188.         frPart = FR_PART_NONE;
  189.     }
  190.  
  191.     for(q = verb; q && frPart; q = q->next) {
  192.         if(q->frPart & frPart) {
  193.             frPart = (FR_PART)(frPart & ~q->frPart);
  194.             TOKEN *altQ = CopyCurrentTree(q, "InsertObjectPronounAfterVerb");
  195.             TOKEN *pronoun = PutNullNoun(FR_PART_NOUN_DEMONSTRATIVE, PRT_CONTROL_ENABLE);
  196.             InsertObjectPronoun(altQ, pronoun, word);
  197.         }
  198.     }
  199.     InsertTOKEN(verb, p);
  200. }
  201.  
  202. void
  203. InsertObjectPronoun(TOKEN *prev, TOKEN *p, char *french)
  204. {
  205.     if(!strcmp(french, "y")) {
  206.     } else if(!strcmp(french, "en")) {
  207.         ChangeToObjectPronoun(p, "en");
  208.         if(IsObjectMatch(prev, FR_PART_VERB) == FALSE) {
  209.             ChangeProperObject(p, FR_PART_PREPOSIT_DE, JP_PROP_ALL);
  210.             p->frPartParent = prev->frPart;
  211.         }
  212.     } else {
  213.         ChangeToObjectPronoun(p, french);
  214.     }
  215.     InsertTOKEN(prev, p);
  216. }
  217.  
  218. //
  219. // pretez-le-moi. -> preler + <me> + <le>
  220. // 補語人称代名詞を処理(肯定命令文のみ)
  221. //
  222. void
  223. ProcessObjectPronoun_Order(TOKEN *start)
  224. {
  225.     TOKEN    *p = start->next;
  226.     TOKEN    *verb = NULL;
  227.     TOKEN    *o1 = NULL, *o2 = NULL, *o3 = NULL;
  228.     TOKEN    *markO1 = NULL, *markO2 = NULL, *markO3 = NULL;
  229.     TOKEN    *en = NULL, *y = NULL;
  230.  
  231.     if(p == NULL
  232.     || (p->frPart & FR_PART_VERB) == FR_PART_NONE
  233.     || p->which
  234.     || (p->frTense & FR_TENSE_ORDER) == FR_TENSE_NONE
  235.     || p->next == NULL
  236.     || p->punctuation != FR_PUNCT_HYPHEN)
  237.         return;
  238.     verb = p;
  239.     p = p->next;
  240.  
  241.     if( p->moved == FALSE
  242.     && IsObjectMatch(p, FR_PART_ARTICLE_PRONOUN)) {
  243.         o2 = p;            // le, la, l', les
  244.         if(p->punctuation != FR_PUNCT_HYPHEN) goto WrapUp;
  245.         p = p->next;
  246.         if(p == NULL)    return;
  247.     }
  248.  
  249.     if( p->moved == FALSE
  250.     && (p->frAttrib & (FR_ATTRIB)(FR_ATTRIB_LEVEL1 | FR_ATTRIB_LEVEL2))) {
  251.         if(((p->frAttrib & FR_ATTRIB_PLURAL) && IsObjectMatch(p, FR_PART_NOUN_OBJECT_I))
  252.         || ((p->frAttrib & FR_ATTRIB_SINGLE) && IsObjectMatch(p, FR_PART_NOUN_PERSONAL))) {
  253.             o1 = p;            // me, te, nous, vous
  254.             if(p->punctuation != FR_PUNCT_HYPHEN) goto WrapUp;
  255.             p = p->next;
  256.             if(p == NULL)    return;
  257.         }
  258.     }
  259.  
  260.     if( p->moved == FALSE
  261.     && (p->frAttrib & FR_ATTRIB_LEVEL3)
  262.     && IsObjectMatch(p, FR_PART_NOUN_OBJECT_I))    {
  263.         // 一つの動詞に目的語は2つまで
  264.         if(o1 && o2) {    markO1 = o1;    o1 = NULL;        }
  265.         o3 = p;            // me, te, nous, vous
  266.         if(p->punctuation != FR_PUNCT_HYPHEN) goto WrapUp;
  267.         p = p->next;
  268.         if(p == NULL)    return;
  269.     }
  270.  
  271.     if(p->frPart == FR_PART_ADVERB_Y) {
  272.         // 一つの動詞に目的語は2つまで
  273.         if(o2 && o3) {    markO2 = o2;    o2 = NULL;        }
  274.         y = p;
  275.         if(p->punctuation != FR_PUNCT_HYPHEN) goto WrapUp;
  276.         p = p->next;
  277.         if(p == NULL)    return;
  278.     }
  279.  
  280.     if(p->frPart == FR_PART_SPECIAL_EN) {
  281.         // 一つの動詞に目的語は2つまで
  282.         if(o3 && y)    {    markO3 = o3;    o3 = NULL;        }
  283.         en = p;
  284.         if(p->punctuation != FR_PUNCT_HYPHEN) goto WrapUp;
  285.         p = p->next;
  286.         if(p == NULL)    return;
  287.     }
  288. WrapUp:
  289.     if(o3)    o1 = o3;    // lui, leurは間接目的語
  290.  
  291.     // 主語がないので、<attrib>は<verb>で調べる
  292.     if(o1 || o2 || y || en)
  293.         SetVerbPronounObject(start, verb, verb, o2, o1, y, en);
  294.  
  295.     if(markO1)    markO1->moved = TRUE;
  296.     if(markO2)    markO2->moved = TRUE;
  297.     if(markO3)    markO3->moved = TRUE;
  298. }
  299.  
  300.  
  301. //
  302. // 補語人称代名詞を動詞の目的語として認識する
  303. //
  304. void
  305. SetVerbPronounObject(TOKEN *start, TOKEN *s, TOKEN *v, 
  306.                      TOKEN *o1, TOKEN *o2, TOKEN *y, TOKEN *en)
  307. {
  308.     // 何らかの理由で以前に却下されている
  309.     if(v->moved)    return;
  310.  
  311.     if(en) {    // il y en a deux -> il a y <en deux>.のために最初に行う
  312.         DisconnectTOKEN(start, en);
  313.         InsertTOKEN(v, en);
  314.         ChangeToObjectPronoun(en, "en");
  315.         en->frPart = FR_PART_NOUN_OBJECT_D;    // (FR_PART)(FR_PART_NOUN_OBJECT_D | FR_PART_NOUN_OBJECT_I);
  316.         en->moved = TRUE;    // 処理済み
  317.     }
  318.  
  319.     if(o2) {
  320.         if(IsObjectMatch(o2, FR_PART_NOUN_RECURSIVE));    // "se"は判断するまでもない
  321.         else if(o2->frAttrib & FR_ATTRIB_LEVEL3)
  322.             o2->frPart = FR_PART_NOUN_OBJECT_I; // lui, leur
  323.         else
  324.             o2->frPart = FR_PART_NOUN_OBJECT_BOTH;    // me, te, nous, vous
  325.         if(s && IsAttribMatch(o2, s)) {    // 主語と同じ<attrib>なら再帰代名詞の可能性もある
  326.             o2->frPart = (FR_PART)(o2->frPart | FR_PART_NOUN_RECURSIVE);
  327.             o2->frAttrib = (FR_ATTRIB)(s->frAttrib & o2->frAttrib);
  328.         }
  329.         DisconnectTOKEN(start, o2);
  330.         InsertTOKEN(v, o2);
  331.         o2->moved = TRUE;    // 処理済み
  332.     }
  333.  
  334.     if(o1) {
  335.         if(o1->frPart == FR_PART_SPECIAL_SE) {
  336.             ChangeToPronoun(o1, "se");
  337.         } else {
  338.             if(s && IsAttribMatch(o1, s)) {    // 主語と同じ<attrib>なら再帰代名詞の可能性もある
  339.                 o1->frPart = (FR_PART)(o1->frPart | FR_PART_NOUN_RECURSIVE);
  340.                 o1->frAttrib = (FR_ATTRIB)(s->frAttrib & o1->frAttrib);
  341.             }
  342.             ChangeToObjectPronoun(o1, GetTokenFrench(o1));
  343.         }
  344.         DisconnectTOKEN(start, o1);
  345.         InsertTOKEN(v, o1);
  346.         o1->moved = TRUE;    // 処理済み
  347.     }
  348.  
  349.     if(y) {
  350.         DisconnectTOKEN(start, y);
  351.         InsertTOKEN(v, y);
  352.         y->moved = TRUE;    // 処理済み
  353.     }
  354.  
  355.     if(o1 || o2 || y || en) {    // 受動態の可能性を消す
  356.         TOKEN *p = s;
  357.         while(p) {
  358.             if(p->frPart & FR_PART_VERB)
  359.                 p->frTense = (FR_TENSE)(p->frTense & ~FR_TENSE_PASSIVE);
  360.             if(p == v) break;
  361.             p = p->next;
  362.         }
  363.     }
  364.     // この動詞は処理済み
  365.     v->moved = TRUE;
  366. }
  367.  
  368.  
  369. //
  370. // 名詞 + 動詞句 → 文章
  371. //
  372. void
  373. CombineSubjectVerb(TOKEN *start)
  374. {
  375.     TOKEN    *p;
  376.     TOKEN    *subject = NULL, *verb = NULL;
  377.  
  378.     for(p = start; p; p = p->next) {
  379.         TOKEN    *next = p->next;
  380.  
  381.         if(IsObjectMatch(p, FR_PART_NOUN_ALL)
  382.         && CanBeSubject(p)
  383.         &&  next
  384.         && (next->frPart & FR_PART_VERB)
  385.         && !(next->frPart & FR_PART_COMBINE)
  386.         &&  next->subject == NULL
  387.         && !(next->frTense & (FR_TENSE)(FR_TENSE_P_PAST | FR_TENSE_P_PRESENT))
  388.         && (p->what == &nullPronoun || !(next->frTense & FR_TENSE_ORIGIN))
  389.         &&  next->which) {
  390.             subject = p;
  391.             verb = p->next;
  392.         }
  393.         if(ToWaitSubjectVerb(p, subject, verb)) {
  394.             subject = verb = NULL;
  395.         }
  396.     }
  397.  
  398.     if(subject == NULL)    return;
  399.  
  400.     // 命令形で主語付き文章は作れない
  401.     if(verb->frTense == FR_TENSE_ORDER) {
  402.         currentTree->prtControl = PRT_CONTROL_DISABLE;
  403.         return;
  404.     }
  405.     CombineSubjectVerb(start, subject, verb);
  406.     if(verb->which) {    // 破棄されていなければ
  407.         verb->scoreCombine += SCORE_MAKE_SENTENCE;
  408.     }
  409. }
  410.  
  411. BOOL
  412. ToWaitSubjectVerb(TOKEN *p, TOKEN *subject, TOKEN *verb)
  413. {
  414.  
  415.     if(verb
  416.     && (p->frPart & FR_PART_PREPOSIT)
  417.     &&  p->frPartParent == FR_PART_VERB
  418.     && MatchParentPreposition(verb, p))
  419.         return(TRUE);
  420.  
  421.     if(p->frPart == FR_PART_COMBINE_NOUN
  422. //    || p->frPart == FR_PART_COMBINE_VERB
  423.     || p->frPart == FR_PART_COMBINE_ADJECTIVE) {
  424.         if(p->object1 == NULL)
  425. //        && p->object2 == NULL)
  426.             return(TRUE);
  427.     }
  428.     // Est-ce que S + V
  429.     if(p->frPart == FR_PART_SPECIAL_ESTCEQUE) {
  430.         return(TRUE);
  431.     }
  432.  
  433.     return(FALSE);
  434. }
  435.  
  436. void
  437. CombineSubjectVerb(TOKEN *start, TOKEN *subject, TOKEN *verb)
  438. {
  439.     TOKEN    *prev = PreviousToken(start, subject, 1);
  440.  
  441.     //    le b[timent @ c`t{ duquele je vois (un clocher est l'h`tel).
  442.     // -> le b[timent @ c`t{ (duquele je vois un clocher) est l'h`tel.
  443.     if(IsObjectMatch(prev, FR_PART_VERB_UNCLEAR)) {
  444.         TOKEN *altP = CopyCurrentTree(subject, "SubjectVerb 1");
  445.         altP->frPartParent = FR_PART_NONE;
  446.         altP->frPartChoice = FR_PART_OBJECT;
  447.     } else if(IsObjectMatch(prev, FR_PART_PREPOSIT_UNCLEAR)) {
  448.         TOKEN *altP = CopyCurrentTree(subject, "SubjectVerb 2");
  449.         altP->frPartParent = FR_PART_PREPOSIT;
  450.         altP->frPartChoice = FR_PART_NONE;
  451.     }
  452.  
  453.     // 命令形ではない
  454.     if(IsTokenFrench(subject, "命令文") == FALSE)
  455.         CancelTenseOrder(verb);
  456.  
  457.     DisconnectTOKEN(start, subject);
  458.  
  459.     verb->subject = subject;
  460.     verb->synSubject = TRUE;
  461.     verb->frPart = (FR_PART)(verb->frPart | FR_PART_SENTENCE_NORMAL);
  462.  
  463.     // j'y vais aussi. <aussi>は、<je>にかかっている
  464.     subject->jpEmphasis |= verb->jpEmphasis;
  465.     ImproveSubjectVerb(subject, verb);
  466. }
  467.  
  468. void
  469. CancelTenseOrder(TOKEN *p)
  470. {
  471.     if(p == NULL)    return;
  472.  
  473.     if(p->frPart & FR_PART_COMBINE) {
  474.         if(p->object1)    CancelTenseOrder(p->object1);
  475.         if(p->object2)    CancelTenseOrder(p->object2);
  476.     }
  477.     p->frTense = (FR_TENSE)(p->frTense & ~FR_TENSE_ORDER);
  478. }
  479.  
  480. void
  481. ImproveSubjectVerb(TOKEN *subject, TOKEN *verb)
  482. {
  483.     if(subject == NULL
  484.     || verb == NULL)
  485.         return;
  486.  
  487.     if(verb->frPart & FR_PART_COMBINE) {
  488.         if(verb->object1)    ImproveSubjectVerb(subject, verb->object1);
  489.         if(verb->object2)    ImproveSubjectVerb(subject, verb->object2);
  490.         return;
  491.     }
  492.  
  493.     // Vous allez chanter. の<vous>と<chanter>の組み合わせは行わない。
  494.     if(subject->frAttrib
  495.     && verb->frAttrib) {
  496.         // 動詞は何種類か候補が或場合が有るので、ここて判定 (je aime, il aimeなど)
  497.         FR_ATTRIB    frAttrib = (FR_ATTRIB)(subject->frAttrib & verb->frAttrib);
  498.         subject->frAttrib = frAttrib;
  499.         verb->frAttrib = frAttrib;
  500.     }
  501.  
  502.     // 再帰代名詞を間違って選択しないように
  503.     if(verb->object1
  504.     && verb->object1->frAttrib != (FR_ATTRIB)(FR_ATTRIB_IL | FR_ATTRIB_ILS)        // "se"は無条件で通す
  505.     && IsObjectMatch(verb->object1, FR_PART_NOUN_RECURSIVE)
  506.     && IsAttribMatch(verb->object1, subject) == FALSE) {
  507.         verb->object1->frPart = (FR_PART)(verb->object1->frPart & ~(FR_PART_NOUN_RECURSIVE & ~FR_PART_ALL));
  508.     }
  509.     if(verb->object2
  510.     && verb->object2->frAttrib != (FR_ATTRIB)(FR_ATTRIB_IL | FR_ATTRIB_ILS)        // "se"は無条件で通す
  511.     && IsObjectMatch(verb->object2, FR_PART_NOUN_RECURSIVE)
  512.     && IsAttribMatch(verb->object2, verb) == FALSE) {
  513.         verb->object2->frPart = (FR_PART)(verb->object2->frPart & ~(FR_PART_NOUN_RECURSIVE & ~FR_PART_ALL));
  514.     }
  515.  
  516.     if(subject->frPart & FR_PART_INTERROGATIVE)
  517.         subject->jpEmphasis = JP_EMPHASIS_GA;
  518.  
  519.     ReconsiderRecursiveObject(subject, verb);
  520.  
  521. // 適当な日本語の動詞を選ぶ(その2)
  522. // (今回は構文を変えずに、主語のpropを考慮し、日本語を選び直す)
  523. //    再帰代名詞なども考慮する
  524.     SelectJpVerb2(subject, verb);
  525.     if(verb == NULL
  526.     || verb->which == NULL)
  527.         return;
  528.  
  529.     JP_VERB    *jpVerb = (JP_VERB*)verb->which;
  530.     TOKEN    *obj1 = verb->object1, *obj2 = verb->object2;
  531.  
  532.     // "il"は、NOUN_SUBJECTかNOUN_IMPERSONALかはっきりさせる
  533.     if(jpVerb->frPart0 == FR_PART_NOUN_IMPERSONAL)
  534.         subject->frPart = FR_PART_NOUN_IMPERSONAL;
  535.  
  536.     ProcessJpHint(subject, verb);
  537. //    sentence->scoreCombine += SCORE_MAKE_SENTENCE;
  538.     verb->jpUnit = subject->jpUnit;    // nous sommes le treize.用
  539.     if(obj1 && !(jpVerb->jpHint & JP_HINT_SVA)) {
  540. //        TOKEN    *obj1 = verb->object1;
  541.         if(obj1->object1 && IsObjectMatch(obj1, FR_PART_PREPOSIT_ALL))
  542.             obj1 = obj1->object1;
  543.         if(IsObjectMatch(obj1, FR_PART_NOUN_ALL))
  544.             SelectJpNoun(verb, obj1, verb, jpVerb->jpProp1);
  545.         if(IsObjectMatch(obj1, FR_PART_ADJECTIVE_GENERAL))        // Paul est grand. ポールは偉大だ -> 大きい
  546.             PrioritizeBehindAdjective(obj1, subject, jpVerb->jpProp1);
  547.         else if(IsObjectMatch(obj1, FR_PART_VERB_INF))
  548.             ImproveSubjectVerb(subject, obj1);
  549.     }
  550.     if(obj2) {
  551.         if(obj2->object1 && IsObjectMatch(obj2, FR_PART_PREPOSIT_ALL))
  552.             obj2 = obj2->object1;
  553.         if(IsObjectMatch(obj2, FR_PART_NOUN_ALL))
  554.             SelectJpNoun(verb, obj2, verb, jpVerb->jpProp2);
  555.         if(IsObjectMatch(obj2, FR_PART_ADJECTIVE_GENERAL))    // Paul est grand. ポールは偉大だ -> 大きい
  556.             PrioritizeBehindAdjective(obj2, subject, jpVerb->jpProp1);
  557.         else if(IsObjectMatch(obj2, FR_PART_VERB_ALL)) {
  558.             if(jpVerb->jpHint & JP_HINT_SVOV)
  559.                 ImproveSubjectVerb(obj1, obj2);
  560.             else
  561.                 ImproveSubjectVerb(subject, obj2);
  562.         }
  563.     }
  564.     if((jpVerb->jpHint & JP_HINT_PUTTOGETHER12)
  565.     && obj1
  566.     && obj2) {
  567.         SelectJpNoun(verb, obj1, verb, obj2->jpProp, jpVerb->jpProp1);
  568.         SelectJpNoun(verb, obj2, verb, obj1->jpProp, jpVerb->jpProp2);
  569.         SelectJpNoun(verb, obj1, verb, obj2->jpProp, jpVerb->jpProp1);
  570.     }
  571.     if((jpVerb->jpHint & JP_HINT_SVOA)
  572.     &&  obj1
  573.     &&  obj2) {
  574.         if(obj2->frPart & FR_PART_ADJECTIVE) {
  575.             if(IsObjectMatch(obj2, FR_PART_ADJECTIVE_GENERAL)
  576.             && !(obj2->frPart & FR_PART_COMBINE)) {
  577.                 //     FR_PART_ADJECTIVE_GENERAL_B / GENERAL_F を取り消す
  578.                 obj2->frPart = FR_PART_ADJECTIVE_GENERAL;
  579.             }
  580.             SelectJpAdjective2(obj1, obj2, verb, FR_LOCATION_BOTH);
  581.         } else if(obj2->frPart & FR_PART_ADVERB) {
  582.             SelectJpAdverb2(obj1, obj2, verb);
  583.         }
  584.     }
  585.     if(jpVerb->Exec)    jpVerb->Exec(verb);
  586. }
  587.  
  588.  
  589. //
  590. // 動詞の目的語の再帰代名詞をチェック
  591. // eg.) allez vous laver les mains.
  592. BOOL
  593. ReconsiderRecursiveObject(TOKEN *subject, TOKEN *verb)
  594. {
  595.     BOOL    hit = FALSE;
  596.  
  597.     // 主語・動詞があること
  598.     if(subject
  599.     && verb
  600.     && (verb->frPart & FR_PART_VERB));
  601.     else return(FALSE);
  602.  
  603.     if(verb->object1) {
  604.         ReconsiderRecursiveObject(subject, verb->object1);    // さらに動詞を目的語としてとっていた場合
  605.         if(verb->object1->frPart == FR_PART_PREPOSIT_A_INF)
  606.             hit |= CheckRecursiveObj(subject, verb->object1->child);
  607.         else if(verb->object1->frPart == FR_PART_PREPOSIT_DE_INF)
  608.             hit |= CheckRecursiveObj(subject, verb->object1->child);
  609.         else if(verb->object1->frPart == FR_PART_VERB_GENERAL)
  610.             hit |= CheckRecursiveObj(subject, verb->object1);
  611.     }
  612.     if(verb->object2) {
  613.         ReconsiderRecursiveObject(subject, verb->object2);    // さらに動詞を目的語としてとっていた場合
  614.         if(verb->object2->frPart == FR_PART_PREPOSIT_A_INF)
  615.             hit |= CheckRecursiveObj(subject, verb->object2->child);
  616.         else if(verb->object2->frPart == FR_PART_PREPOSIT_DE_INF)
  617.             hit |= CheckRecursiveObj(subject, verb->object2->child);
  618.         else if(verb->object2->frPart == FR_PART_VERB_GENERAL)
  619.             hit |= CheckRecursiveObj(subject, verb->object2);
  620.     }
  621.     return(hit);
  622. }
  623.  
  624. BOOL
  625. CheckRecursiveObj(TOKEN *subject, TOKEN *verb)
  626. {
  627.     if(verb
  628.     && verb->frPart == FR_PART_VERB_GENERAL
  629.     && verb->frTense == FR_TENSE_ORIGIN) {
  630.         if((verb->object1 && ConsiderRecursiveObject(subject, verb->object1)
  631.         || (verb->object2 && ConsiderRecursiveObject(subject, verb->object2)))) {
  632.             SelectJpVerb2(subject, verb);
  633.             return(TRUE);
  634.         }
  635.     }
  636.     return(FALSE);
  637. }
  638.  
  639. //
  640. // JP_HINTを用いて、日本語訳を向上させる
  641. //
  642. void
  643. ProcessJpHint(TOKEN *subject, TOKEN *verb)
  644. {
  645.     if(subject == NULL || verb == NULL)
  646.         return;
  647.  
  648.     JP_VERB    *jpVerb = (JP_VERB *)verb->which;
  649.     if(jpVerb == NULL) return;
  650.  
  651.     if((jpVerb->jpHint & JP_HINT_SVA)
  652.     && (verb->object1)) {
  653.         ProcessJpHint_SVA(subject, verb);
  654.     }
  655.  
  656.     if((jpVerb->jpHint & JP_HINT_VOLUME1_ADVERB)
  657.     && (verb->object1) // 姉妹しか一人いない -> 一人の姉妹しかいない
  658.     && (verb->object1->jpEmphasis & JP_EMPHASIS_ONLY) == 0) {
  659.         MoveVolumeToAdverb(verb, verb->object1);
  660.     }
  661.     if((jpVerb->jpHint & JP_HINT_PLACE_OBJECT1)
  662.     && verb->object1) { // 私はあそこに店を見る -> 私はあそこの店を見る
  663.         TOKEN    *adverb = DisconnectChildToken(verb, FR_PART_ADVERB_ALL, JP_PROP_PLACE);
  664.         if(adverb) {
  665.             AddChildTOKEN(verb->object1, adverb);
  666.             SelectJpAdverb2(verb->object1, adverb, NULL);
  667.         }
  668.     }
  669.     if((jpVerb->jpHint & JP_HINT_PLACE1_ADVERB)
  670.     && verb->object1) {
  671.         TOKEN    *prep = DisconnectChildToken(verb->object1, FR_PART_PREPOSIT_ALL, JP_PROP_PLACE);
  672.         if(prep == NULL)
  673.             prep = DisconnectChildToken(verb->object1, FR_PART_PREPOSIT_DE, JP_PROP_PLACE);
  674.         if(prep) {
  675.             AddChildTOKEN(verb, prep);
  676.             SelectJpPreposition2(verb, prep);
  677.             prep->jpEmphasis |= JP_EMPHASIS_COMMA;
  678.         }
  679.     }
  680.     if((jpVerb->jpHint & JP_HINT_TIME1_ADVERB)
  681.     && verb->object1) {
  682.         TOKEN    *prep = DisconnectChildToken(verb->object1, FR_PART_PREPOSIT_ALL, JP_PROP_TIME);
  683.         if(prep) {
  684.             AddChildTOKEN(verb, prep);
  685.             SelectJpPreposition2(verb, prep);
  686.             prep->jpEmphasis |= JP_EMPHASIS_COMMA;
  687.         }
  688.     }
  689.     if((jpVerb->jpHint & JP_HINT_TIME1_ADVERB)
  690.     && verb->object1) {
  691.         TOKEN    *prep = DisconnectChildToken(verb->object1, FR_PART_PREPOSIT_ALL, JP_PROP_TIME);
  692.         if(prep) {
  693.             AddChildTOKEN(verb, prep);
  694.             SelectJpPreposition2(verb, prep);
  695.             prep->jpEmphasis |= JP_EMPHASIS_COMMA;
  696.         }
  697.     }
  698.     if((jpVerb->jpHint & JP_HINT_AUXILIARY)
  699.     && verb->object1) {
  700.         TOKEN    *child, *object = verb->object1;
  701.         if((object->frPart & FR_PART_PREPOSIT)
  702.         && object->object1)
  703.             object = object->object1;        // A_INF, DE_INF
  704.         child = object->child;
  705.         object->child = NULL;
  706.         if(child) {
  707.             AddChildTOKEN(verb, child);
  708.         }
  709.     }
  710.  
  711.     if((subject->frPart & FR_PART_NOUN)
  712.     && !(jpVerb->jpHint & JP_HINT_SVA)) {        // SVAは、すでに処理済み
  713. //    && !(jpVerb->jpHint & JP_HINT_PUTTOGETHER12)) {
  714.         SelectJpNoun(verb, subject, verb, jpVerb->jpProp0);
  715.         if(jpVerb->jpHint & JP_HINT_HUMAN) {
  716.             SelectJpNoun(verb, subject, verb, JP_PROP_HUMAN, jpVerb->jpProp0);
  717.             if(!(subject->jpProp & JP_PROP_HUMAN))
  718.                 subject->scoreCombine += SCORE_STRANGE_SUBJECT;
  719.         }
  720.     }
  721.  
  722.     if((verb->jpProp & JP_PROP_PASSIVE)
  723.     && (jpVerb->jpHint & JP_HINT_HUMAN)) {
  724.         TOKEN    *par = SearchToken(FR_PART_PREPOSIT_PAR, verb->child);
  725.         if(par)    
  726.             SelectJpNoun(verb, par->object1, verb, JP_PROP_HUMAN);
  727.         else {
  728.             TOKEN *de = SearchToken(FR_PART_PREPOSIT_DE, verb->child);
  729.             if(de) SelectJpNoun(verb, de->object1, verb, JP_PROP_HUMAN);
  730.         }
  731.     }
  732.     if((jpVerb->jpHint & JP_HINT_DATE_SUBJECT)
  733.     && verb->object1) { // c'etais mendi heir 昨日、月曜日だった -> 昨日は月曜日だった
  734.         TOKEN    *adverb = SearchToken(FR_PART_ADVERB_ALL, JP_PROP_TIME, verb->child);
  735.         if(adverb == NULL)
  736.             adverb = SearchToken(FR_PART_ADVERB_ALL, JP_PROP_TIME, verb->child);
  737.         if(adverb) {
  738.             adverb->jpEmphasis |= JP_EMPHASIS_HA;
  739.             // 昨日は、月曜日だった -> 昨日は月曜日だった eg) Hier c'{tait dimanche.
  740.             adverb->jpEmphasis -= JP_EMPHASIS_COMMA;
  741.         }
  742.     }
  743.  
  744.     if(jpVerb->jpHint & JP_HINT_COMPARE1) {
  745.         // ビールよりも私はとてもワインが好きだ -> ビールよりも私はワインが好きだ
  746.         TOKEN    *mieux = SearchToken(FR_PART_ADVERB_COMPARE, verb->child);
  747.         if(mieux) {
  748.             mieux->prtControl = PRT_CONTROL_DISABLE;
  749.             if(verb->object1)    verb->object1->jpEmphasis |= JP_EMPHASIS_HOU;
  750.         }
  751.     }
  752.     if(jpVerb->jpHint & JP_HINT_COMPARE2) {
  753.         // ビールよりも私はとてもワインが好きだ -> ビールよりも私はワインが好きだ
  754.         TOKEN    *mieux = SearchToken(FR_PART_ADVERB_COMPARE, verb->child);
  755.         if(mieux) {
  756.             mieux->prtControl = PRT_CONTROL_DISABLE;
  757.             if(verb->object2)    verb->object2->jpEmphasis |= JP_EMPHASIS_HOU;
  758.         }
  759.     }
  760.     if((verb->object1)
  761.     &&(jpVerb->jpHint & JP_HINT_SUCCEED_TENSE1)) {    // あなたは私を手伝った必要がある -> あなたは私を手伝う必要があった
  762.         verb->frTense = verb->object1->frTense;
  763.         verb->object1->frTense = FR_TENSE_PRESENT;
  764.     }
  765.     if((verb->object1)
  766.     &&(jpVerb->jpHint & JP_HINT_DUMMY_NEGATIVE1)) {    // 虚辞の<ne>
  767.         verb->object1->jpProp &= (~JP_PROP_NEGATIVE);
  768.         if(verb->object1->object2)
  769.             verb->object1->object2->jpProp &= (~JP_PROP_NEGATIVE);
  770.     }
  771.     if((verb->object1)
  772.     &&(jpVerb->jpHint & JP_HINT_RSUBJECT1)) {
  773.         TOKEN    *rv = SearchToken(FR_PART_RELATIVE_SUBJECT, verb->object1->child);
  774.         if(rv
  775.         && rv->object1
  776.         && IsObjectMatch(rv->object1, FR_PART_VERB_ALL)) {
  777.             DisconnectChildToken(verb->object1, FR_PART_RELATIVE_SUBJECT, JP_PROP_NONE);
  778.             verb->object2 = rv->object1;
  779.             verb->object2->frTense = FR_TENSE_ORIGIN;
  780. //            verb->object2->frTense = (FR_TENSE)(verb->object2->frTense | FR_TENSE_ORIGIN);
  781.             SelectJpVerb2(subject, verb);
  782.         }
  783.     }
  784.     if(jpVerb->jpHint & JP_HINT_NO_NEGATIVE) {
  785.         verb->jpProp &= ~JP_PROP_NEGATIVE;
  786.         verb->jpProp &= ~JP_PROP_NEGATIVE2;
  787.     }
  788. }
  789.  
  790. void
  791. ProcessJpHint_SVA(TOKEN *subject, TOKEN *verb)
  792. {
  793.     JP_VERB    *jpVerb = (JP_VERB *)verb->which;
  794.     if(jpVerb == NULL) return;
  795.  
  796.     do {
  797.         if(IsObjectMatch(verb->object1, FR_PART_NOUN_OBJECT_D)
  798.         && verb->object1->frAttrib == FR_ATTRIB_IL)
  799.             ImproveJapanese(subject, verb->object1, verb, JP_PROP_THING, jpVerb->jpProp0);    // nous le somme. 私もそれだ
  800.         else
  801.             ImproveJapanese(subject, verb->object1, verb, subject->jpProp, jpVerb->jpProp1);
  802.  
  803.         if(jpVerb->jpHint & JP_HINT_HUMAN)
  804.             ImproveJapanese(subject, subject, verb, JP_PROP_HUMAN, jpVerb->jpProp0);
  805.         else
  806.             ImproveJapanese(subject, subject, verb, verb->object1->jpProp, jpVerb->jpProp0);
  807.  
  808.         if(IsObjectMatch(verb->object1, FR_PART_ADJECTIVE_GENERAL))        // Paul est grand. ポールは偉大だ -> 大きい
  809.             PrioritizeBehindAdjective(verb->object1, subject, jpVerb->jpProp1);
  810.  
  811.     } while(FlipCmpAdjective(verb, verb->object1));    // le moins -> le plus
  812. }
  813.  
  814. //
  815. // 名詞を修飾していた数詞を動詞修飾にする
  816. // eg) 私は一台の車を持っている -> 私は車を一台持っている。
  817. void
  818. MoveVolumeToAdverb(TOKEN *verb, TOKEN *obj)
  819. {
  820.     if(verb == NULL || obj == NULL || obj->child == NULL)    return;
  821.  
  822.     TOKEN *num = SearchToken(FR_PART_NUMETRIC_NUMBER, obj->child);
  823.     if(num == NULL)    return;    //    数詞はない
  824.  
  825.     DisconnectChildToken(obj, num);
  826.     AddChildTOKEN(verb, num);
  827.  
  828.     // 1台<の>車を持っている -> 車を1台持っている
  829.     num->jpEmphasis |= JP_EMPHASIS_NOTAIL;
  830. }
  831.  
  832.  
  833. //
  834. // 動詞句(命令形) → 文章
  835. //
  836. void
  837. ChangeOrderVerbToSentence(TOKEN *start)
  838. {
  839.     TOKEN    *p = start;
  840.     TOKEN    *lastVerb = NULL;
  841.  
  842.     // 文末が"?"で終わっている
  843.     if(currentTree->punctuation == FR_PUNCT_QUESTION)    return;
  844.  
  845.     for(p = start; p; p = p->next) {
  846.         if(p->frPart & FR_PART_COMBINE)
  847.             continue;
  848.         if(p->frPart & FR_PART_VERB)
  849.             lastVerb = p;        // 動詞が2つ以上有る
  850.         if((p->frPart & FR_PART_SPECIAL)
  851.         && p->frPart != FR_PART_SPECIAL_COMMA)
  852.             lastVerb = NULL;    // 未解決の単語が残っている
  853.     }
  854.     if(lastVerb == NULL)    return;
  855.  
  856.     p = start->next;
  857.     if( p
  858.     &&  p->subject == NULL
  859.     &&  p == lastVerb        // ただ1つの動詞があること
  860.     && (p->frPart & FR_PART_VERB)
  861.     && p->which) {
  862.         if(p->frTense & FR_TENSE_ORDER) {
  863.             if(p->frAttrib & (FR_ATTRIB_LEVEL1 | FR_ATTRIB_LEVEL2))    // 命令形で3人称はない
  864.                 p->frAttrib = (FR_ATTRIB)(p->frAttrib & ~FR_ATTRIB_LEVEL3);    
  865.             if(!(p->frAttrib & FR_ATTRIB_PLURAL))     // 単数形なら2人称のはず    eg) Leve-toi. Leveは1,2,3単
  866.                 p->frAttrib = (FR_ATTRIB)(p->frAttrib & ~FR_ATTRIB_LEVEL1);
  867.             ChangeOrderVerbToSentence(start, lastVerb);
  868.         } else if((p->frTense & FR_TENSE_ORIGIN)
  869.                 && (p->frPartChoice & FR_PART_INDEPENDENCE)) {
  870.             ChangeOrderVerbToSentence(start, lastVerb);
  871.         }
  872.     }
  873. }
  874.  
  875. void
  876. ChangeOrderVerbToSentence(TOKEN *start, TOKEN *verb)
  877. {
  878.     const static char    *dummystr = "命令文";
  879.  
  880.     TOKEN *subject  = PutToken(FR_PART_NOUN_SUBJECT,
  881.         verb->frAttrib,   JP_PROP_HUMAN, &dummystr);    // 命令形なのだから 主語は人?
  882.     subject->prtControl = PRT_CONTROL_DISABLE;    // dummy subjectは表示しない
  883.     verb->frPart = (FR_PART)(verb->frPart | FR_PART_SENTENCE_ORDER);
  884.     verb->subject = subject;    // 動詞
  885.     verb->scoreCombine += SCORE_MAKE_ORDER;
  886.  
  887.     ChangeVerbTenseToOrder(verb);
  888.     SelectJpVerb2(subject, verb);    // まずは、命令形専用の辞書
  889.     // 目的語に動詞を持つ場合 eg) allez vous laver les mains.
  890.     ReconsiderRecursiveObject(subject, verb);
  891. }
  892.  
  893. void
  894. ChangeVerbTenseToOrder(TOKEN *verb)
  895. {
  896.     if(verb->frPart & FR_PART_COMBINE) {
  897.         if(verb->object1)
  898.             ChangeVerbTenseToOrder(verb->object1);
  899.         if(verb->object2)
  900.             ChangeVerbTenseToOrder(verb->object2);
  901.         return;
  902.     }
  903.     if(verb->frTense & FR_TENSE_ORIGIN)
  904.         verb->frTense = (FR_TENSE)(FR_TENSE_ORIGIN | FR_TENSE_ORDER);
  905.     else
  906.         verb->frTense = FR_TENSE_ORDER;
  907. }
  908.  
  909. //
  910. // 動詞句+ 目的語 → 動詞句
  911. //
  912. void
  913. CombineVerbObject(TOKEN *start)
  914. {
  915.     TOKEN    *p;
  916.     TOKEN    *lastVerb = NULL;
  917.  
  918.     // 後ろにある動詞から解析を始める
  919.     for(p = start; p; p= p->next) {
  920.         if((p->frPart & FR_PART_VERB)
  921.         && p->subject == NULL    // 主語なし
  922.         && !(p->frPart & FR_PART_COMBINE)
  923.         &&  p->which == NULL
  924.         && !(p->frTense == FR_TENSE_ORIGIN && p->which)        // aller + inf -> 近未来 allerに注目する必要がある
  925.         && !(p->frTense == FR_TENSE_P_PAST && p->which)) {    // etre + pp -> 受動態 etreに注目する必要がある
  926.             lastVerb = p;
  927.         }
  928.         // なんか問題になるような条件があったら、ここでlastVerb = NULL;する
  929.         if(ToWaitCombineVerbObject(p, lastVerb))
  930.             lastVerb = NULL;
  931.     }
  932.  
  933.     if(lastVerb != NULL && lastVerb->which == NULL) {
  934.         if(lastVerb->next
  935.         && lastVerb->preposition
  936.         && MatchAdjectiveObject(lastVerb->next, lastVerb->preposition)) {
  937.             // orthographe de laquelle vous ne serez pas s~r.
  938.             // -> orthographe laquelle vous ne serez <de+NULL> pas s~r.
  939.             // -> orthographe laquelle vous ne serez pas s~r <de+NULL>
  940.             CombineAdjectiveObject(start, lastVerb->next, lastVerb->preposition);
  941.             lastVerb->preposition = NULL;
  942.         } else {
  943.             SelectJpVerb1(lastVerb);
  944.             if(lastVerb->which) {
  945.                 // 動詞の訳を選んだら、副詞も検討し直す
  946.                 ImproveJapanese(lastVerb, lastVerb->child, lastVerb, JP_PROP_ALL, JP_PROP_ALL);
  947.             }
  948.         }
  949.     }
  950. }
  951.  
  952. //
  953. // 動詞 + 目的語の連結を待つべきか?
  954. //
  955. BOOL
  956. ToWaitCombineVerbObject(TOKEN *p, TOKEN *verb)
  957. {
  958.     // 通すもの
  959.     if(p->frPart == FR_PART_SPECIAL_COMMA
  960.     || p->frPart == FR_PART_SPECIAL_AUSSI)
  961.         return(FALSE);
  962.  
  963.     // 主語が確定していれば通す
  964.     if(p->subject) {
  965.         if(p->frPart == FR_PART_SENTENCE_QUE
  966.         || p->frPart == FR_PART_SENTENCE_ORIGIN)
  967.         return(FALSE);
  968.     }
  969.  
  970.     // 問答無用
  971.     if((p->frPart & FR_PART_RELATIVE)
  972.     ||  p->frPart == FR_PART_INTERROGATIVE_UNCLEAR
  973.     || (p->frPart & FR_PART_SPECIAL))
  974.         return(TRUE);
  975.  
  976.     // object1 = object2 = NULLなら
  977.     if(p->object1 == NULL && p->object2 == NULL) {
  978.         if(p->frPart & FR_PART_PREPOSIT)
  979.             return(TRUE);
  980.     }
  981.  
  982.     if(p->object1 == NULL || p->object2 == NULL) {
  983.         if(p->frPart == FR_PART_COMBINE_NOUN
  984.         || p->frPart == FR_PART_COMBINE_ADJECTIVE
  985.         || p->frPart == FR_PART_COMBINE_PREPOSIT)
  986.             return(TRUE);
  987.     }
  988.  
  989.     return(FALSE);
  990. }
  991.  
  992. //
  993. // 動詞の適当な日本語訳を選ぶ
  994. //
  995. void
  996. SelectJpVerb1(TOKEN *verb)
  997. {
  998.     if((verb->frTense & FR_TENSE_PASSIVE)
  999.     || (verb->frTense == FR_TENSE_P_PAST)) {
  1000.         verb->which = NULL;                        // 候補をクリア
  1001.         SelectJpVerb1_Passive(verb, TRUE);        // 受動態専用の候補のみ
  1002.         if(verb->which == NULL)
  1003.             SelectJpVerb1_Passive(verb, FALSE);    // 一般的な訳も候補に入れる
  1004.     }
  1005.     if(verb->which == NULL) {
  1006.         // 受動態の訳がなければ、能動態の訳を探す
  1007.         SelectJpVerb1_Active(verb);
  1008.     }
  1009.  
  1010.     if(verb->which) {
  1011.         JP_VERB    *jpVerb = (JP_VERB *)verb->which;
  1012.         JP_PROP    savProp = verb->jpProp * (~JP_PROP_ALL);
  1013.  
  1014.         verb->jpProp = savProp | jpVerb->myJpProp;
  1015.  
  1016.         if(verb->object1) JpVerbPostProcess1(verb, verb->object1, jpVerb->jpProp1);
  1017.         if(verb->object2) JpVerbPostProcess1(verb, verb->object2, jpVerb->jpProp2);
  1018.         
  1019.         // il accepte de venir avec nous. (avec nousはaccepteではなくvenirに掛るべき)
  1020.         TOKEN    *next = verb->next;
  1021. #if 1
  1022.         if(next) {
  1023.             if(VerbObjectPreposition(verb, verb->object2) == FALSE) {
  1024.                 VerbObjectPreposition(verb, verb->object1);
  1025.             }
  1026.         }
  1027. #endif
  1028.         for(TOKEN *q = verb->child; q; q = q->next)
  1029.             q->scoreCombine += SCORE_INSERTED_ADVERB;
  1030.     }
  1031. }
  1032.  
  1033. //
  1034. // SelectJpVerb1の後処理
  1035. //
  1036. void
  1037. JpVerbPostProcess1(TOKEN *verb, TOKEN *object, JP_PROP jpProp)
  1038. {
  1039.  
  1040.     if(object->frPart & FR_PART_COMBINE) {
  1041.         JpVerbPostProcess1(verb, object->object1, jpProp);
  1042.         JpVerbPostProcess1(verb, object->object2, jpProp);
  1043.         return;
  1044.     }
  1045.  
  1046.     JpVerbPostProcess(verb, object, jpProp);
  1047.  
  1048.     if(object->frPart & FR_PART_PREPOSIT) {
  1049.         object->scoreCombine += SCORE_VERB_PREPOSITION;
  1050.     }
  1051.  
  1052.     // 一般名詞を冠詞/所有形容詞無しで使ったな -> 減点
  1053.     if(IsObjectMatch(object, FR_PART_NOUN_GENERAL)
  1054.     && !HasArticleOrUnique(object)) {
  1055.         object->scoreCombine += SCORE_NO_ARTICLE_NOUN;
  1056.     }
  1057.     if(CheckUnnaturalObject(object)) {
  1058.         verb->scoreSelect = 0;    // いくら動詞が良い訳でもねぇ...
  1059.         object->scoreCombine += SCORE_VERB_STRANGE_OBJECT;
  1060.     }
  1061. }
  1062.  
  1063. void
  1064. JpVerbPostProcess(TOKEN *verb, TOKEN *object, JP_PROP jpProp)
  1065. {
  1066.     if(object->frPart & FR_PART_COMBINE) {
  1067.         JpVerbPostProcess(verb, object->object1, jpProp);
  1068.         JpVerbPostProcess(verb, object->object2, jpProp);
  1069.         return;
  1070.     }
  1071.  
  1072.     // 日本語訳に前置詞が含まれていた場合外す。
  1073.     if(object->frPart & FR_PART_PREPOSIT) {
  1074.         // 前置詞ではなく、名詞を選択する。
  1075.         TOKEN    *noun = object->object1;
  1076.         SelectJpNoun(verb, noun, verb, jpProp);
  1077.         SetPrtControlReplace(object);
  1078.         // il ne fait pitie a personne. personneの"誰<にも>"を動詞に伝える
  1079.         if(object->object1)
  1080.             object->jpEmphasis = object->object1->jpEmphasis;
  1081.     } else if(object->frPart & FR_PART_VERB) {
  1082.         // nous devons ]tre fatigue.
  1083.         object->frTense = (FR_TENSE)(object->frTense & ~FR_TENSE_ORDER);
  1084.         if(IsObjectMatch(object, FR_PART_SENTENCE_QUE))
  1085.             object->prtControl = PRT_CONTROL_REPLACED;
  1086.     } else if(IsObjectMatch(object, FR_PART_NOUN_OBJECT_D, JP_PROP_NONE, NULL, "en")) {
  1087.         object->prtControl = PRT_CONTROL_DISABLE;
  1088.     }
  1089.  
  1090.     if(CheckUnnaturalObject(object)) {
  1091.         verb->scoreSelect = 0;    // いくら動詞が良い訳でもねぇ...
  1092.     }
  1093. }
  1094.  
  1095. void
  1096. SetPrtControlReplace(TOKEN *p)
  1097. {
  1098.     if(p->prtControl == PRT_CONTROL_ENABLE) {
  1099.         if(p->frPart & FR_PART_COMBINE) {
  1100.             if(p->object1)    SetPrtControlReplace(p->object1);
  1101.             if(p->object2)    SetPrtControlReplace(p->object2);
  1102.         } else {
  1103.             p->prtControl = PRT_CONTROL_REPLACED;
  1104.         }
  1105.     }
  1106. }
  1107.  
  1108.  
  1109. //
  1110. // 動詞の目的語としてより、副詞の方が似合っているもの
  1111. // (Il est juste) dix heures -> Il est (juste) dix heures.
  1112. //
  1113. char    *unnaturalObjects[] = {
  1114.     "aujourd'hui",
  1115.     "encore",
  1116.     "juste",
  1117.     "toujours",
  1118.     "tous",
  1119.     "tout",
  1120.     ""    // End Code
  1121. };
  1122.  
  1123. BOOL
  1124. CheckUnnaturalObject(TOKEN *p)
  1125. {
  1126.     for(int i = 0; unnaturalObjects[i][0]; i++) {
  1127.         if(IsTokenFrench(p, unnaturalObjects[i]))
  1128.             return(TRUE);
  1129.     }
  1130.     return(FALSE);
  1131. }
  1132.  
  1133.  
  1134. //
  1135. // Verb + Object 後続の前置詞の処理
  1136. // eg) il accepte de venir avec nous
  1137. // avec nousは accepteではなく venirに掛るべき
  1138. //
  1139. BOOL
  1140. VerbObjectPreposition(TOKEN *verb, TOKEN *object)
  1141. {
  1142.     if(verb == NULL
  1143.     || verb->next == NULL
  1144.     || object == NULL)
  1145.         return(FALSE);
  1146.  
  1147.     TOKEN    *next = verb->next;
  1148.  
  1149.     if(object->frPart == FR_PART_PREPOSIT_A_INF
  1150.     || object->frPart == FR_PART_PREPOSIT_DE_INF)
  1151.         object = object->object1;
  1152.     if(object == NULL)    return(FALSE);
  1153.  
  1154.     if((next->frPart & FR_PART_PREPOSIT)
  1155.     && MatchParentPreposition(object, next)) {
  1156.         CombineParentPreposition(verb, object, next);
  1157.         return(TRUE);
  1158.     }
  1159.     return(FALSE);
  1160. }
  1161.  
  1162. // 動詞の適当な日本誤訳を選ぶ(能動態)
  1163. // (構文解析のため、後でCombineSubjectVerb()関数で
  1164. //    propを踏まえて再び最適な日本語を選ぶ)
  1165. void
  1166. SelectJpVerb1_Active(TOKEN *verb)
  1167. {
  1168.     JP_VERB    const *jpVerb  = ((VERB *)verb->what)->jpVerb;
  1169.     int            proposed = ((VERB *)verb->what)->proposed;
  1170.  
  1171.     TOKEN        *obj1 = verb->next;
  1172.     TOKEN        *obj2 = NULL;
  1173.     TOKEN        *hitObj1 = NULL, *hitObj2 = NULL;
  1174.  
  1175.     if(obj1 != NULL)    obj2 = verb->next->next;
  1176.  
  1177.     while(proposed-- > 0) {
  1178.         int cmp = -1;
  1179.  
  1180.         if(verb->frCompose != FR_COMPOSE_NONE
  1181.         && verb->frCompose != jpVerb->frCompose)
  1182.             goto NotMatch;
  1183.  
  1184.         if(verb->preposition != NULL) {
  1185.             // 前置詞つきの関係代名詞から、前置詞を引き継いだ場合
  1186.             cmp = CmpVerbObject(jpVerb, obj1, verb->preposition);
  1187.             if(cmp >= 1)    hitObj1 = obj1;
  1188.             if(cmp >= 2)    hitObj2 = verb->preposition;
  1189.             if(cmp < 0) {
  1190.                 cmp = CmpVerbObject(jpVerb, verb->preposition, obj1);
  1191.                 if(cmp >= 1)    hitObj1 = verb->preposition;
  1192.                 if(cmp >= 2)    hitObj2 = obj1;
  1193.             }
  1194.         } else {
  1195.             int    savCmp = cmp = CmpVerbObject(jpVerb, obj1, obj2);
  1196.             if(cmp >= 1)    hitObj1 = obj1;
  1197.             if(cmp >= 2)    hitObj2 = obj2;
  1198.             if(cmp <= 0 ) {
  1199. //            && jpVerb->frPart2 != FR_PART_NONE) {
  1200. //                順序を変えて再検査
  1201.                 cmp = CmpVerbObject(jpVerb, obj2, obj1);
  1202.                 if(cmp == 2) {
  1203.                     hitObj1 = obj2;
  1204.                     hitObj2 = obj1;
  1205.                 } else if(cmp == 1
  1206.                 && (obj1->frPartParent & FR_PART_VERB)
  1207.                 && (IsObjectMatch(obj1, FR_PART_PREPOSIT_ALL) || IsObjectMatch(obj1, FR_PART_ADVERB_ALL))) {
  1208.                     hitObj1 = obj2;
  1209.                     hitObj2 = NULL;
  1210.                     obj1->frPartParent = FR_PART_VERB;
  1211.                     // Elle parle (le plus souvent) de la classe.
  1212.                     // -> Elle parle de la classe (le plus souvent)
  1213.                     // は、ちょっと不自然
  1214.                     obj1->scoreCombine += SCORE_INSERTED_ADVERB;
  1215.                 } else
  1216.                     cmp = savCmp;    // 0 or -1
  1217. //                else cmp = -1;    // cmp == 1は、無視する
  1218.             }
  1219.         }
  1220.         if(cmp < 0) goto NotMatch;
  1221.         // !! BINGO !!
  1222.         if(hitObj1) {
  1223.             ChangeProperObject(hitObj1, jpVerb->frPart1, jpVerb->jpProp1);
  1224.             ConsiderRecursiveObject(verb, hitObj1);
  1225.             if(hitObj1 == verb->preposition)    verb->preposition = NULL;
  1226.             else                                DisconnectTOKEN(verb, hitObj1);
  1227.             verb->object1 = hitObj1;
  1228.         }
  1229.         if(hitObj2) {
  1230.             ChangeProperObject(hitObj2, jpVerb->frPart2, jpVerb->jpProp2);
  1231.             ConsiderRecursiveObject(verb, hitObj2);
  1232.             if(hitObj2 == verb->preposition)    verb->preposition = NULL;
  1233.             else                                DisconnectTOKEN(verb, hitObj2);
  1234.             verb->object2 = hitObj2;
  1235.         }
  1236.         // 辞書にヒットしなかった前置詞を復帰
  1237.         if(verb->preposition) GetBackPreposition(verb);
  1238.  
  1239.         verb->scoreSelect = proposed * SCORE_SELECT_VERB;
  1240.         UpdateJpVerb(verb, jpVerb);
  1241.         isChanged     = TRUE;
  1242.         return;
  1243. NotMatch:
  1244.         jpVerb++;
  1245.     }
  1246. /*
  1247.     まだ目的語が後に来る可能性がある
  1248.     e.g) c'est la voiture que vous avez achet{e.
  1249.  
  1250.     cerr << "Internal Error <SelectJpVerb1>" << endl;
  1251.     TermProgram(-1);
  1252. */
  1253. }
  1254.  
  1255.  
  1256. int
  1257. CmpVerbObject(const JP_VERB *jpVerb, TOKEN *obj1, TOKEN *obj2)
  1258. {
  1259.     int        cntHit = 0;
  1260.  
  1261.     if(jpVerb->SEval) {
  1262.         // 主語チェックのあるものは、ここでははじく
  1263.         // SelectJpVerb2で復活させる
  1264.         return(-1);    
  1265.     } else if(jpVerb->frPart1 != FR_PART_NONE) {
  1266.         if(obj1 == NULL) return(-1);
  1267.         if(obj1->frPart == FR_PART_PREPOSIT_DE
  1268.         && jpVerb->frPart1 == FR_PART_PREPOSIT_ALL)
  1269.             return(-1);
  1270.         if(!IsObjectMatch(obj1, FR_PART_INTERROGATIVE_ALL)
  1271.         && IsObjectMatch(obj1, FR_PART_NOUN_OBJECT_BOTH)
  1272.         && obj1->moved != 1)
  1273.             return(-1);    // 本当は人称代名詞を探していた
  1274.         if(CompareObject(obj1, jpVerb->frPart1, jpVerb->jpProp1, jpVerb->OEval1, jpVerb->str1)) {
  1275.             cntHit++;
  1276.         } else return(-1);
  1277.     }
  1278.     if(jpVerb->frPart2 != FR_PART_NONE) {
  1279.         if(obj2 == NULL)    return(-1);
  1280.         if(obj2->frPart == FR_PART_PREPOSIT_DE
  1281.         && jpVerb->frPart2 == FR_PART_PREPOSIT_ALL)
  1282.             return(-1);
  1283.         if(!IsObjectMatch(obj2, FR_PART_INTERROGATIVE_ALL)
  1284.         && IsObjectMatch(obj2,  FR_PART_NOUN_OBJECT_BOTH)
  1285.         && obj2->moved != 1)
  1286.             return(-1);    // 本当は人称代名詞を探していた
  1287.         if(CompareObject(obj2, jpVerb->frPart2, jpVerb->jpProp2, jpVerb->OEval2, jpVerb->str2)) {
  1288.             cntHit++;
  1289.         } else return(-1);
  1290.     }
  1291.     return(cntHit);
  1292. }
  1293.  
  1294.  
  1295. BOOL
  1296. CompareObject(TOKEN *p, FR_PART frPart, JP_PROP jpProp, BOOL (*Eval)(TOKEN *), char *str)
  1297. {
  1298.  
  1299.     if(p == NULL
  1300.     || !(p->frPartChoice & FR_PART_OBJECT))
  1301.         return(FALSE);    // これは、動詞の目的語にならない
  1302.  
  1303.     if((p->frPart & FR_PART_COMBINE)
  1304.     && (p->frPart & FR_PART_PREPOSIT)) {
  1305.         frPart = (FR_PART)(frPart | FR_PART_COMBINE);
  1306.     }
  1307.  
  1308.     return(IsObjectMatch(p, frPart, jpProp, Eval, str));
  1309. }
  1310.  
  1311.  
  1312. //
  1313. // CombineVerbObejct処理後、行き場のない前置詞を復活する
  1314. //
  1315. void
  1316. GetBackPreposition(TOKEN *verb)
  1317. {
  1318.     TOKEN    *preposition = verb->preposition;
  1319.  
  1320.     if(preposition == NULL)    return;
  1321.     verb->preposition = NULL;
  1322.  
  1323.     // 後ろ(object2)から検索
  1324.     if(verb->object2
  1325.     && SelectJpPreposition2(verb->object2, preposition)) {
  1326.         AddChildTOKEN(verb->object2, preposition);
  1327.     } else if(verb->object1
  1328.     && SelectJpPreposition2(verb->object1, preposition)) {
  1329.         AddChildTOKEN(verb->object1, preposition);
  1330.     } else {
  1331.         InsertTOKEN(verb, preposition);
  1332.     }
  1333. }
  1334.  
  1335. // 動詞の適当な日本誤訳を選ぶ(受動態)
  1336. // (構文解析のため、後でCombineSubjectVerb()関数で
  1337. //    propを踏まえて再び最適な日本語を選ぶ)
  1338. //    passiveVoiceOnly : JP_PROP_PASSIVEのみを相手にするか?
  1339. void
  1340. SelectJpVerb1_Passive(TOKEN *verb, BOOL passiveVoiceOnly)
  1341. {
  1342.     JP_VERB    const    *jpVerb  = ((VERB *)verb->what)->jpVerb;
  1343.     int            proposed = ((VERB *)verb->what)->proposed;
  1344.     TOKEN        *de_subject = NULL;        // par ~, de~などの動作主
  1345.     TOKEN        *object2;
  1346.  
  1347.     while(proposed-- > 0) {
  1348.         if(passiveVoiceOnly
  1349.         && (jpVerb->myJpProp & JP_PROP_PASSIVE) == 0)
  1350.             goto NotMatch;
  1351.  
  1352.         object2 = NULL;
  1353.  
  1354.         // 非人称主語は受け身をとらない
  1355.         if(jpVerb->frPart0 == FR_PART_NOUN_IMPERSONAL
  1356.         || jpVerb->frPart1 == FR_PART_NOUN_RECURSIVE)
  1357.             goto NotMatch;
  1358.  
  1359.         // 受け身になるのは、名詞だけ
  1360.         if((jpVerb->frPart1 & FR_PART_NOUN) == FR_PART_NONE)
  1361.             goto NotMatch;
  1362.  
  1363.         if(jpVerb->frPart2 != FR_PART_NONE) {
  1364.             object2 = GetProperObject(verb, jpVerb->frPart2, jpVerb->jpProp2);
  1365.             if(object2 == NULL)    goto NotMatch;
  1366.         }
  1367.         // !! BINGO !!
  1368.         if(object2) {
  1369.             ChangeProperObject(object2, jpVerb->frPart2, jpVerb->jpProp2);
  1370.             DisconnectTOKEN(verb, object2);
  1371.         }
  1372.  
  1373.         UpdateJpVerb(verb, jpVerb);
  1374.         verb->scoreSelect = 0;
  1375.         verb->jpProp  |= JP_PROP_PASSIVE;
  1376.         verb->object1 = NULL;
  1377.         verb->object2 = object2;
  1378.         verb->frTense = (FR_TENSE)(verb->frTense | FR_TENSE_PASSIVE);
  1379.         isChanged = TRUE;
  1380.         
  1381.         // もしあれば、動作主を探す
  1382.         do {
  1383.             if(verb->jpProp & JP_PROP_ACTION) {
  1384.                 de_subject = SearchToken(FR_PART_PREPOSIT_PAR, verb);
  1385.                 if(IsObjectMatch(de_subject, FR_PART_NOUN_OBJECT_BOTH))    de_subject = NULL;    // me, te, ...
  1386.             }
  1387.             if(de_subject == NULL) {
  1388.                 de_subject = SearchToken(FR_PART_PREPOSIT_DE, verb);
  1389.                 if(IsObjectMatch(de_subject, FR_PART_NOUN_OBJECT_BOTH))    de_subject = NULL;    // me, te, ...
  1390.             }
  1391.         } while(de_subject && de_subject == object2);    // de_subject = object2 == NULLは通す
  1392.         if(de_subject) {
  1393.             AttatchParentPreposition(verb, verb, de_subject);
  1394.             de_subject->scoreCombine += SCORE_PASSIVE_SUBJECT;
  1395.         }
  1396.         return;
  1397. NotMatch:
  1398.         jpVerb++;
  1399.     }
  1400. /*
  1401.     まだ目的語が後に来る可能性がある
  1402.     e.g) c'est la voiture que vous avez achet{e.
  1403.  
  1404.     cerr << "Internal Error <SelectJpVerb1>" << endl;
  1405.     TermProgram(-1);
  1406. */
  1407. }
  1408.  
  1409. //
  1410. // 受動態の処理 (etre + 過去分詞) -> 受身
  1411. //
  1412. void
  1413. ProcessPassiveVoice(TOKEN *start)
  1414. {
  1415.     TOKEN    *p;
  1416.     TOKEN    *lastEtre = NULL, *lastVerb = NULL;
  1417.  
  1418.     for(p = start; p; p = p->next) {
  1419.         if(p->frPart & FR_PART_COMBINE)
  1420.             continue;
  1421.         else if(p->subject)
  1422.             continue;
  1423.         else if(IsObjectMatch(p, FR_PART_VERB, JP_PROP_NONE, NULL, "]tre"))
  1424.             lastEtre = p;
  1425.         else if(p-> frPart & FR_PART_VERB)
  1426.             lastVerb = p;
  1427.     }
  1428.  
  1429.     if(lastEtre
  1430.     && lastEtre->which == NULL
  1431.     && lastVerb
  1432.     && lastVerb->which
  1433.     && (lastVerb->frTense & FR_TENSE_PASSIVE)
  1434.     && lastEtre->next == lastVerb)
  1435.         CombineEtrePastParticiple(start, lastEtre, lastVerb);
  1436. }
  1437.  
  1438. const JP_VERB
  1439. *MatchVerbObject(TOKEN *verb, TOKEN *object1, TOKEN *object2)
  1440. {
  1441.     const JP_VERB    *jpVerb  = ((VERB *)verb->what)->jpVerb;
  1442.     int                proposed = ((VERB *)verb->what)->proposed;
  1443.  
  1444.     while(proposed-- > 0) {
  1445.         int cmp = CmpVerbObject(jpVerb, object1, object2);
  1446.         if(cmp == 2)
  1447.             return(jpVerb);
  1448.         if(cmp <= 0
  1449.         && CmpVerbObject(jpVerb, object2, object1) == 2)
  1450.             return(jpVerb);
  1451.  
  1452.         jpVerb++;
  1453.     }
  1454.     return(NULL);
  1455. }
  1456.  
  1457. void
  1458. SelectJpVerb2(TOKEN *subject, TOKEN *verb)
  1459. {
  1460.     if(verb->frPart & FR_PART_COMBINE) {
  1461.         if(verb->object1)
  1462.             SelectJpVerb2(subject, verb->object1);
  1463.         if(verb->object2)
  1464.             SelectJpVerb2(subject, verb->object2);
  1465.         return;
  1466.     }
  1467.  
  1468.     // 否定、疑問、受動態などの情報
  1469.     JP_PROP    savJpProp = (JP_PROP)(verb->jpProp * ~JP_PROP_ALL);
  1470.  
  1471.     if(verb->frTense == FR_TENSE_ORDER) {                // 命令形
  1472.         verb->which = NULL;
  1473.         SelectJpVerb2_Order(verb, TRUE);                // 命令形専用の候補のみ
  1474.         if(verb->which == NULL)
  1475.             SelectJpVerb2_Order(verb, FALSE);            // 一般的な訳も候補に入れる
  1476.     } else if((verb->frTense & FR_TENSE_PASSIVE)
  1477.     || (verb->frTense & FR_TENSE_ETRE_PASSIVE)) {        // 受動態
  1478.         SelectJpVerb2_Passive(subject, verb);
  1479.         verb->jpProp |= JP_PROP_PASSIVE;
  1480.     } else
  1481.         SelectJpVerb2_Active(subject, verb);
  1482.  
  1483.     if(verb->which == NULL) {
  1484.         currentTree->prtControl = PRT_CONTROL_DISABLE;
  1485.     } else {
  1486.         JP_VERB    *jpVerb = (JP_VERB *)verb->which;
  1487.         verb->jpProp = (JP_PROP)(jpVerb->myJpProp | savJpProp);
  1488.         if(jpVerb->jpHint & JP_HINT_SVOA)
  1489.             verb->scoreCombine  += SCORE_VERB_SVOA;
  1490.         if(verb->object1) JpVerbPostProcess(verb, verb->object1, jpVerb->jpProp1);
  1491.         if(verb->object2) JpVerbPostProcess(verb, verb->object2, jpVerb->jpProp2);
  1492.     }
  1493. }
  1494.  
  1495. void
  1496. SelectJpVerb2_Active(TOKEN *subject, TOKEN *verb)
  1497. {
  1498.     JP_PROP    mask = verb->jpProp * (JP_PROP_NEGATIVE | JP_PROP_PASSIVE);
  1499.  
  1500.     verb->which = NULL;
  1501.     SelectJpVerb2_Active(subject, verb, mask);                    // 否定形専用の候補のみ
  1502.  
  1503.     if(verb->which == NULL) {
  1504.         SelectJpVerb2_Active(subject, verb, JP_PROP_NONE);
  1505.     }
  1506.     
  1507. }
  1508.  
  1509. void
  1510. SelectJpVerb2_Active(TOKEN *subject, TOKEN *verb, JP_PROP mask)
  1511. {
  1512.     JP_VERB    const *jpVerb  = ((VERB *)verb->what)->jpVerb;
  1513.     int        proposed = ((VERB *)verb->what)->proposed;
  1514.  
  1515.     while(proposed-- > 0) {
  1516.         if(!(mask == JP_PROP_NONE || (jpVerb->myJpProp & mask)))
  1517.             goto NotMatch;
  1518.         if(jpVerb->frPart0 == FR_PART_NONE
  1519.         && subject)
  1520.             goto NotMatch;
  1521.         if(jpVerb->frPart0 != FR_PART_NONE) {
  1522.             if(!subject
  1523.             || !IsObjectMatch(subject, jpVerb->frPart0, jpVerb->jpProp0, NULL, NULL)
  1524.             || (jpVerb->SEval && jpVerb->SEval(subject, verb) == FALSE))
  1525.                 goto NotMatch;
  1526.         }
  1527.         if(jpVerb->frPart1 != FR_PART_NONE) {
  1528.             if(! CompareObject(verb->object1, jpVerb->frPart1, jpVerb->jpProp1, jpVerb->OEval1, jpVerb->str1))
  1529.                 goto NotMatch;
  1530.         }
  1531.         if(jpVerb->frPart2 != FR_PART_NONE) {
  1532.             if(! CompareObject(verb->object2, jpVerb->frPart2, jpVerb->jpProp2, jpVerb->OEval2, jpVerb->str2))
  1533.                 goto NotMatch;
  1534.         }
  1535.         // すでに、複合過去形として処理されたもの
  1536.         if(verb->frCompose != FR_COMPOSE_NONE
  1537.         && verb->frCompose != jpVerb->frCompose) {
  1538.             verb->which = NULL;        // この候補は無効
  1539.             goto    NotMatch;
  1540.         }
  1541.         verb->scoreSelect = proposed * SCORE_SELECT_VERB;
  1542.         UpdateJpVerb(verb, jpVerb);
  1543.         return;
  1544. NotMatch:
  1545.         jpVerb++;
  1546.     }
  1547. //    verb->score = SCORE_UNCLEAR_WORD;
  1548. }
  1549.  
  1550. void
  1551. SelectJpVerb2_Passive(TOKEN *subject, TOKEN *verb)
  1552. {
  1553.     JP_PROP    mask = verb->jpProp * (JP_PROP_NEGATIVE | JP_PROP_PASSIVE);
  1554.  
  1555.     verb->which = NULL;
  1556.     SelectJpVerb2_Passive(subject, verb, mask);                    // 受動態専用の候補のみ
  1557.     if(verb->which == NULL) {
  1558.         mask &= ~JP_PROP_PASSIVE;
  1559.         SelectJpVerb2_Passive(subject, verb, mask);                // 一般的な訳も候補に入れる
  1560.     }
  1561.     if(verb->which == NULL) {
  1562.         SelectJpVerb2_Passive(subject, verb, JP_PROP_NONE);        // 一般的な訳も候補に入れる
  1563.     }
  1564. }
  1565.  
  1566. void
  1567. SelectJpVerb2_Passive(TOKEN *subject, TOKEN *verb, JP_PROP mask)
  1568. {
  1569.     JP_VERB    const *jpVerb  = ((VERB *)verb->what)->jpVerb;
  1570.     int        proposed = ((VERB *)verb->what)->proposed;
  1571.  
  1572.     // 動作主
  1573.     TOKEN    *par = SearchToken(FR_PART_PREPOSIT_PAR, verb->child);
  1574.     if(par == NULL)    par = SearchToken(FR_PART_PREPOSIT_DE, verb->child);
  1575.     if(par)    par = par->object1;
  1576.  
  1577.     while(proposed-- > 0) {
  1578.         if(!(mask == JP_PROP_NONE || (jpVerb->myJpProp & mask)))
  1579.             goto NotMatch;
  1580.  
  1581.         if(jpVerb->frPart0 == FR_PART_NONE
  1582.         || jpVerb->frPart0 == FR_PART_NOUN_IMPERSONAL    // 非人称主語は受け身をとらない
  1583.         || jpVerb->frPart1 == FR_PART_NONE                // 他動詞のみ考慮
  1584.         || jpVerb->frPart1 == FR_PART_NOUN_RECURSIVE)
  1585.             goto NotMatch;
  1586.  
  1587.         if(par
  1588.         && jpVerb->str0        // 変な指定があった場合
  1589.         && !IsObjectMatch(par, jpVerb->frPart0, jpVerb->jpProp0, NULL, jpVerb->str0))
  1590.             goto NotMatch;
  1591.  
  1592.         if(subject != NULL
  1593.         && !IsObjectMatch(subject, jpVerb->frPart1, jpVerb->jpProp1, NULL, NULL))
  1594.             goto NotMatch;
  1595.  
  1596.         if(jpVerb->frPart2 != FR_PART_NONE) {
  1597.             if(! CompareObject(verb->object2, jpVerb->frPart2, jpVerb->jpProp2, jpVerb->OEval2, jpVerb->str2))
  1598.                 goto NotMatch;
  1599.         }
  1600.  
  1601.         if(verb->which != (void *)jpVerb) {
  1602.             verb->which = (void *)jpVerb;
  1603.             verb->jpProp = jpVerb->myJpProp;
  1604.             isChanged = TRUE;
  1605.         }
  1606.         return;
  1607. NotMatch:
  1608.         jpVerb++;
  1609.     }
  1610. }
  1611.  
  1612. //
  1613. // 命令形動詞の日本語訳を探す
  1614. //
  1615. void
  1616. SelectJpVerb2_Order(TOKEN *verb, BOOL orderTenseOnly)
  1617. {
  1618.     JP_VERB    const *jpVerb  = ((VERB *)verb->what)->jpVerb;
  1619.     int        proposed = ((VERB *)verb->what)->proposed;
  1620.  
  1621.     while(proposed-- > 0) {
  1622.         if(orderTenseOnly) {
  1623.             if(jpVerb->frPart0 != FR_PART_NONE)    goto NotMatch;
  1624.         } else {
  1625.             // やっぱり、命令は人に言うものでは...
  1626.             if(!(jpVerb->frPart0 & FR_PART_NOUN)
  1627.             || !(jpVerb->jpProp0 & JP_PROP_HUMAN)
  1628.             || jpVerb->SEval)        // 評価したいが主語はない
  1629.                 goto NotMatch;
  1630.         }
  1631.         if(jpVerb->frPart1 != FR_PART_NONE) {
  1632.             if(! CompareObject(verb->object1, jpVerb->frPart1, jpVerb->jpProp1, jpVerb->OEval1, jpVerb->str1))
  1633.                 goto NotMatch;
  1634.         } else if(verb->object1)    goto NotMatch;
  1635.         if(jpVerb->frPart2 != FR_PART_NONE) {
  1636.             if(! CompareObject(verb->object2, jpVerb->frPart2, jpVerb->jpProp2, jpVerb->OEval2, jpVerb->str2))
  1637.                 goto NotMatch;
  1638.         } else if(verb->object2)    goto NotMatch;
  1639.         verb->scoreSelect = proposed * SCORE_SELECT_VERB;
  1640.         UpdateJpVerb(verb, jpVerb);
  1641.         return;
  1642. NotMatch:
  1643.         jpVerb++;
  1644.     }
  1645. }
  1646.  
  1647. BOOL
  1648. UpdateJpVerb(TOKEN *p, JP_VERB const *jpVerb)
  1649. {
  1650.     VERB    *verb = (VERB *)p->what;
  1651.  
  1652.     if((JP_VERB *)p->which != jpVerb) {
  1653.         JP_PROP    jpProp = (p->jpProp * ~JP_PROP_ALL);
  1654.         p->which = (void *)jpVerb;
  1655.         p->jpProp = (jpProp | jpVerb->myJpProp);
  1656.         isChanged = TRUE;
  1657.         return(TRUE);
  1658.     }
  1659.     return(FALSE);
  1660. }
  1661.  
  1662. TOKEN
  1663. *GetProperObject(TOKEN *p, FR_PART frPart, JP_PROP jpProp)
  1664. {
  1665.     if(p == NULL || p->next == NULL)    return(NULL);
  1666.  
  1667.     p = SearchToken(frPart, p->next);
  1668.     if(p
  1669.     && IsObjectMatch(p, frPart, jpProp, NULL, NULL))
  1670.         return(p);
  1671.  
  1672.     return(NULL);
  1673. }
  1674.  
  1675.  
  1676. //
  1677. // 再帰代名詞をチェック
  1678. //
  1679. BOOL
  1680. ConsiderRecursiveObject(TOKEN *verb, TOKEN *obj)
  1681. {
  1682.     if(verb && obj    // 動詞と目的語がある
  1683.     && (IsObjectMatch(obj, FR_PART_NOUN_OBJECT_D)
  1684.      || IsObjectMatch(obj, FR_PART_NOUN_OBJECT_I))
  1685.     && !IsObjectMatch(obj, FR_PART_NOUN_RECURSIVE)) {
  1686.         FR_ATTRIB    attrib = (FR_ATTRIB)(verb->frAttrib & obj->frAttrib);
  1687.         if((attrib & (FR_ATTRIB_LEVEL1 | FR_ATTRIB_LEVEL2))    // 3人称は'se'(lui, leurなどは再帰代名詞ではない)
  1688.         && (attrib & (FR_ATTRIB_SINGLE | FR_ATTRIB_PLURAL))
  1689.         && (attrib & (FR_ATTRIB_MALE   | FR_ATTRIB_FEMALE))) {
  1690.             obj->frPart = (FR_PART)(obj->frPart | FR_PART_NOUN_RECURSIVE);
  1691.             return(TRUE);
  1692.         }
  1693.     }
  1694.     return(FALSE);
  1695. }
  1696.  
  1697. //
  1698. // 複合過去形を処理
  1699. // (深く吟味せず、安易に2つの候補を作成する)
  1700. //
  1701. void
  1702. ProcessComposePasse(TOKEN *start)
  1703. {
  1704.     TOKEN    *p = start;
  1705.     TOKEN    *lastEtre = NULL, *lastAvoir = NULL;
  1706.     TOKEN    *lastRien = NULL;
  1707.  
  1708.     while(p) {
  1709.         if(p->frPart & FR_PART_VERB) {
  1710.             if(p->frTense & FR_TENSE_P_PAST) {
  1711.                 if(lastEtre) {    // etre + pp
  1712.                     if(HasEtreCompose(p)) {
  1713.                         TOKEN *altP = CopyCurrentTree(p, "ProcessComposePasse");
  1714.                         p->frCompose = FR_COMPOSE_ETRE;
  1715.                         MakeComposePasse(start, lastEtre, p, lastRien);    // 候補1 etre + pp -> 複合過去
  1716.                         altP->frTense = FR_TENSE_PASSIVE;                // 候補2 etre + pp -> 受動態
  1717.                     } else {
  1718.                         p->frTense = FR_TENSE_PASSIVE;            // 確定   etre + pp -> 受動態
  1719.                         lastEtre = NULL;
  1720.                     }
  1721.                 }
  1722.                 if(lastAvoir) {        // avoir + pp -> 複合過去
  1723.                     p->frCompose = FR_COMPOSE_AVOIR;
  1724.                     MakeComposePasse(start, lastAvoir, p, lastRien);
  1725.                 }
  1726.                 if(lastRien) {
  1727.                 }
  1728.                 lastEtre = lastAvoir = lastRien = NULL;
  1729.             } else if(IsObjectMatch(p ,FR_PART_VERB_GENERAL, JP_PROP_NONE, NULL, "]tre")
  1730.             && p->object1 == NULL && p->object2 == NULL)    {
  1731.                 lastEtre = p;        lastAvoir = NULL;
  1732.                 p = SkipSubject(p);
  1733.             } else if(IsObjectMatch(p, FR_PART_VERB_GENERAL, JP_PROP_NONE, NULL, "avoir")
  1734.             && p->object1 == NULL && p->object2 == NULL)    {
  1735.                 lastEtre = NULL;    lastAvoir = p;
  1736.                 p = SkipSubject(p);
  1737.             }
  1738.         } else if(IsObjectMatch(p, FR_PART_NOUN_INDEFINIT, JP_PROP_NONE, NULL, "rien")) {
  1739.             lastRien = p;
  1740.         } else if(!IsObjectMatch(p, FR_PART_ADVERB_ALL)) {    
  1741.             // etreとppの間に副詞が入ることもある。    eg) je ne me suis pas lev{.    
  1742.             lastEtre = lastAvoir = lastRien = NULL;
  1743.         }
  1744.         p = p->next;
  1745.     }
  1746. }
  1747.  
  1748. //
  1749. // 倒置形疑問文の主語を飛ばす
  1750. //
  1751. TOKEN
  1752. *SkipSubject(TOKEN *p)
  1753. {
  1754.     if( p->next        // le lui avez-vous donn{? vousを飛ばす
  1755.     && (p->punctuation & FR_PUNCT_HYPHEN)
  1756.     && IsObjectMatch(p->next, FR_PART_NOUN_SUBJECT)) {
  1757.         p = p->next;
  1758.         if(IsObjectMatch(p, FR_PART_NOUN_OBJECT_BOTH))
  1759.             p->frPart = FR_PART_NOUN_SUBJECT;
  1760.     }
  1761.     return(p);
  1762. }
  1763.  
  1764. //
  1765. // 複合過去を作るのにetreを使う場合があるか?
  1766. //
  1767. BOOL
  1768. HasEtreCompose(TOKEN *p)
  1769. {
  1770.     JP_VERB    const *jpVerb = ((VERB *)p->what)->jpVerb;
  1771.     int        proposed = ((VERB *)p->what)->proposed;
  1772.  
  1773.     while(proposed -- > 0) {
  1774.         if(jpVerb->frCompose & FR_COMPOSE_ETRE)    return(TRUE);
  1775.         jpVerb++;
  1776.     }
  1777.     return(FALSE);
  1778. }
  1779. //
  1780. // JP_HINT_SVOAを持っているか?
  1781. //
  1782. BOOL
  1783. HasJpHintSVOA(TOKEN *p)
  1784. {
  1785.     JP_VERB    const *jpVerb = ((VERB *)p->what)->jpVerb;
  1786.     int        proposed = ((VERB *)p->what)->proposed;
  1787.  
  1788.     while(proposed -- > 0) {
  1789.         if(jpVerb->jpHint & JP_HINT_SVOA)    return(TRUE);
  1790.         jpVerb++;
  1791.     }
  1792.     return(FALSE);
  1793. }
  1794.  
  1795.  
  1796. //
  1797. // 
  1798. //
  1799. BOOL
  1800. HasPrepositionObject(TOKEN *verb, TOKEN *prep)
  1801. {
  1802.     if(  verb == NULL
  1803.     || !(verb->frPart & FR_PART_VERB))
  1804.         return(FALSE);
  1805.  
  1806.     if(verb->frPart & FR_PART_COMBINE) {
  1807.         if(verb->object2)    verb = verb->object2;
  1808.         else    return(FALSE);
  1809.     }
  1810.  
  1811.     JP_VERB    const    *jpVerb  = ((VERB *)verb->what)->jpVerb;
  1812.     int            proposed = ((VERB *)verb->what)->proposed;
  1813.  
  1814.     while(proposed-- > 0) {
  1815.         if(CompareObject(prep, jpVerb->frPart1, jpVerb->jpProp1, jpVerb->OEval1, jpVerb->str1)
  1816.         || CompareObject(prep, jpVerb->frPart2, jpVerb->jpProp2, jpVerb->OEval2, jpVerb->str2)) {
  1817.             return(TRUE);
  1818.         }
  1819.         jpVerb++;
  1820.     }
  1821.     return(FALSE);
  1822. }
  1823.  
  1824. //
  1825. // 名詞 + 現在/過去分詞
  1826. //
  1827. void
  1828. CombineNounParticiple(TOKEN *start)
  1829. {
  1830.     TOKEN    *p = start;
  1831.     TOKEN    *lastNoun = NULL, *lastVerb = NULL;
  1832.  
  1833.     while(p && p->next) {
  1834.         TOKEN    *next = p->next;
  1835.  
  1836.         if(IsObjectMatch(p, FR_PART_NOUN_GENERAL)    // 代名詞に分詞補語は付かない。一般名詞のみ
  1837.         && (next->frPart & FR_PART_VERB)
  1838.         &&  next->which
  1839.         && (next->frTense & (FR_TENSE)(FR_TENSE_PASSIVE | FR_TENSE_P_PAST | FR_TENSE_P_PRESENT))) {
  1840.             // 名詞 + 過去分詞 or 名詞 + 現在分詞
  1841.             lastNoun = p;    lastVerb = next;
  1842.         }
  1843.         p = next;
  1844.     }
  1845.  
  1846.     if(lastVerb == NULL)    return;
  1847.  
  1848.     if(lastVerb->frTense & FR_TENSE_P_PRESENT) {
  1849.         // 現在分詞
  1850.         if(lastVerb->which == NULL)    return;
  1851.     } else {    
  1852.         // 過去分詞
  1853.         if(IsAlwaysIntransitiveVerb(lastVerb))    return;
  1854.     }
  1855.  
  1856.     DisconnectTOKEN(start, lastVerb);
  1857.     AddChildTOKEN(lastNoun, lastVerb);
  1858.  
  1859.     if(lastVerb->frTense & (FR_TENSE)(FR_TENSE_PASSIVE | FR_TENSE_P_PAST)) {
  1860.         SelectJpVerb2_Passive(lastNoun, lastVerb);
  1861.         lastVerb->jpProp |= JP_PROP_PASSIVE;
  1862.  
  1863.         // l'amour perdu 失われる恋愛 -> 失われた恋愛
  1864.         if(lastVerb->jpProp & JP_PROP_ACTION)
  1865.             lastVerb->frTense = (FR_TENSE)(lastVerb->frTense | FR_TENSE_PASSE);
  1866.     } else if(lastVerb->frTense == FR_TENSE_P_PRESENT)     // 名詞 + 現在分詞ならもう一度、訳を考える(名詞は主格)
  1867.         SelectJpVerb2_Active(lastNoun, lastVerb);
  1868.  
  1869.     if(lastVerb->which == NULL)
  1870.         currentTree->prtControl = PRT_CONTROL_DISABLE;
  1871. }
  1872.  
  1873. //
  1874. // avoirと過去分詞動詞をまとめる
  1875. //
  1876. void
  1877. MakeComposePasse(TOKEN *start, TOKEN *avoir, TOKEN *pp, TOKEN *rien)
  1878. {
  1879.     FR_TENSE    tense = avoir->frTense;
  1880.     JP_PROP        savJpProp = (JP_PROP)(avoir->jpProp * ~JP_PROP_ALL);
  1881.  
  1882.     if(tense & FR_TENSE_ORIGIN)                        // avoir chante
  1883.         pp->frTense = FR_TENSE_ORIGIN_C;
  1884.     else if(tense & FR_TENSE_PRESENT)                // j'ai chante
  1885.         pp->frTense = FR_TENSE_PASSE_C;
  1886.     else if(tense & FR_TENSE_IMPERFECT)                // j'avais chante
  1887.         pp->frTense = FR_TENSE_PLUS_PERFECT;
  1888.     else if(tense & FR_TENSE_FUTURE_SIMPLE)            // j'aurai chante
  1889.         pp->frTense = FR_TENSE_FUTURE_ANTERIEUR;
  1890.     else if(tense & FR_TENSE_CONDITIONAL_PRESENT)    // j'aurais chante
  1891.         pp->frTense = FR_TENSE_CONDITIONAL_PASSE;
  1892.     else if(tense & FR_TENSE_SUBJUNCTIVE_PRESENT)    // j'ait chante
  1893.         pp->frTense = FR_TENSE_SUBJUNCTIVE_PASSE;
  1894.     else if(tense & FR_TENSE_SUBJUNCTIVE_IMPERFECT)    // j'eusse chante
  1895.         pp->frTense = FR_TENSE_SUBJUNCTIVE_PASSE;
  1896.     else
  1897.         return;
  1898.  
  1899.     pp->frTense = (FR_TENSE)(pp->frTense & ~FR_TENSE_P_PAST & ~FR_TENSE_PASSIVE);
  1900.     // 命令形を継続 eg) Ayez achev{ ce travail.
  1901.     pp->frTense = (FR_TENSE)(pp->frTense | (FR_TENSE)(tense & FR_TENSE_ORDER));
  1902.     pp->frAttrib = avoir->frAttrib;
  1903.     pp->punctuation = avoir->punctuation;
  1904.     pp->jpProp = (JP_PROP)(pp->jpProp | savJpProp);
  1905.     pp->jpProp = (JP_PROP)(pp->jpProp * ~JP_PROP_PASSIVE);
  1906.     pp->scoreCombine += SCORE_COMPOSE_C;
  1907.     TOKEN    *adverb = avoir->child;        // avoirが既に副詞を持っている可能性もある。  eg) je ne l'ai jamai vu. 
  1908.     if(adverb) {
  1909.         AddChildTOKEN(pp, adverb);
  1910.         ImproveJapanese(pp, adverb, pp, JP_PROP_ALL, JP_PROP_ALL);
  1911.         // 後で、減点の対象とならないように    Je suis <souvent> all{ @ Londres.
  1912.         for(TOKEN *q = adverb; q; q = q->next)
  1913.             q->scoreCombine -= SCORE_INSERTED_ADVERB;
  1914.     }
  1915.     if(IsTokenFrench(avoir, "]tre")
  1916.     &&  avoir->object1
  1917.     && (avoir->object1->frPart & FR_PART_ADVERB)) {    // 副詞が属詞として処理されてしまった場合 eg) je suis souvent all{ @ Londres.
  1918.         AddChildTOKEN(pp, avoir->object1);
  1919.         ImproveJapanese(pp, avoir->object1, pp, JP_PROP_ALL, JP_PROP_ALL);
  1920.     }
  1921.     // <avoir>の位置に動詞をまとめる
  1922.     // le lui avez-vous donne?    -> le lui donne-vous?
  1923.     DisconnectTOKEN(start, pp);
  1924.     SwapToken(avoir, pp);
  1925.  
  1926.     if(rien) {
  1927.         DisconnectTOKEN(start, rien);
  1928.         InsertTOKEN(avoir, rien);
  1929.     }
  1930. }
  1931.  
  1932. //
  1933. // 受動態を作る
  1934. //
  1935. void
  1936. CombineEtrePastParticiple(TOKEN *start, TOKEN *etre, TOKEN *pp)
  1937. {
  1938.     pp->frAttrib = etre->frAttrib;
  1939.     // 否定とか質問とか
  1940.     pp->jpProp    = (JP_PROP)(pp->jpProp | (JP_PROP)(etre->jpProp * ~JP_PROP_ALL));
  1941.     
  1942.     // 過去形とか
  1943.     pp->frTense    = (FR_TENSE)(pp->frTense | etre->frTense | FR_TENSE_ETRE_PASSIVE);
  1944.     pp->frTense = (FR_TENSE)(pp->frTense & ~FR_TENSE_PASSIVE);
  1945.  
  1946.     // <etre>が複合過去だったかもしれない?
  1947.     pp->scoreCombine += etre->scoreCombine;
  1948.  
  1949.     // etreに付いていた副詞を保存
  1950.     if(etre->child)
  1951.         AddChildTOKEN(pp, etre->child);
  1952.  
  1953.     DisconnectTOKEN(start, etre);
  1954. }
  1955.  
  1956.  
  1957. //
  1958. // 自動詞を他動詞に変換する
  1959. // eg) un devoir @ finir 終わるべき宿題 -> 終わらせるべき宿題
  1960. //
  1961. void
  1962. ChangeIntransitiveVerbToTransitive(TOKEN *noun, TOKEN *prep)
  1963. {
  1964.     TOKEN    *verb = NULL;
  1965.  
  1966.     if(prep == NULL)    goto Error;
  1967.  
  1968.     verb = prep->object1;
  1969.     if(verb == NULL
  1970.     || !(verb->frPart & FR_PART_VERB))    goto Error;
  1971.  
  1972.     // 元から他動詞
  1973.     if(verb->object1 || verb->object2)    return;
  1974.  
  1975.     // 他動詞となりえない
  1976.     if(IsAlwaysIntransitiveVerb(verb) == FALSE) {
  1977.         TOKEN *null = PutNullNoun();
  1978.         null->jpProp = noun->jpProp;
  1979.         null->frAttrib = noun->frAttrib;
  1980.         InsertTOKEN(verb, null);
  1981.         verb->which = NULL;
  1982.         SelectJpVerb1(verb);
  1983.         if(verb->which == NULL)    goto Error;
  1984.         if(verb->object1 != null && verb->object2 != null)
  1985.             DisconnectTOKEN(verb, null);
  1986.     }
  1987.     return;
  1988. Error:
  1989.     PrintInternalError( "Itnernal Error <ChangeIntransitiveVerbToTransitive>\n");
  1990. }
  1991.  
  1992. //
  1993. // いつも自動詞か(他動詞とならないか)?
  1994. //
  1995. BOOL
  1996. IsAlwaysIntransitiveVerb(TOKEN *verb)
  1997. {
  1998.     if(verb == NULL
  1999.     || !(verb->frPart & FR_PART_VERB))
  2000.         return(FALSE);
  2001.  
  2002.     JP_VERB    const *jpVerb  = ((VERB *)verb->what)->jpVerb;
  2003.     int        proposed = ((VERB *)verb->what)->proposed;
  2004.  
  2005.     while(proposed-- > 0) {
  2006.         if(jpVerb->frPart1 & FR_PART_NOUN) return(FALSE);
  2007.         if(jpVerb->frPart2 & FR_PART_NOUN) return(FALSE);
  2008.         jpVerb++;
  2009.     }
  2010.     return(TRUE);
  2011. }
  2012.  
  2013. //
  2014. // 動詞原形を名詞化する。
  2015. //
  2016. void
  2017. ChangeVerbToNoun(TOKEN *start)
  2018. {
  2019.     TOKEN    *prev = start;
  2020.     TOKEN    *p = prev;
  2021.  
  2022.     for(p = start; p; p = p->next) {
  2023.         if( p->which        // すでにObjectが確定していること
  2024.         && (p->frPart & FR_PART_VERB)
  2025.         && (p->frTense & FR_TENSE_ORIGIN)
  2026.         && (p->frPartChoice & FR_PART_NOUN)
  2027.         && !IsObjectMatch(prev, FR_PART_VERB_UNCLEAR)) {    // 動詞辞書の方で、拾ってもらおう
  2028.             TOKEN    *altP = CopyCurrentTree(p, "ChangeVerbToNoun", FR_PART_NOUN);
  2029.             FR_PART    frPart = (FR_PART)(p->frPart & FR_PART_COMBINE);    // <et>が付いていた場合
  2030.             p->frPart = (FR_PART)(FR_PART_NOUN_VERB | frPart);
  2031.             isChanged = TRUE;
  2032.         }
  2033.         prev = p;
  2034.     }
  2035. }
  2036.  
  2037.  
  2038. //
  2039. // 過去分詞の形容詞化
  2040. //
  2041. void
  2042. ChangeParticipleToAdjective(TOKEN *start)
  2043. {
  2044.     TOKEN    *p;
  2045.     TOKEN    *lastVerb = NULL;
  2046.  
  2047.     for(p = start; p; p = p->next) {
  2048.         if(IsObjectMatch(p, FR_PART_VERB_UNCLEAR)
  2049.         && (p->frTense & (FR_TENSE)(FR_TENSE_PASSIVE | FR_TENSE_P_PAST))) {
  2050.             lastVerb = p;
  2051.         }
  2052.     }
  2053.  
  2054.     if(lastVerb == NULL
  2055.     || IsAlwaysIntransitiveVerb(lastVerb))
  2056.         return;
  2057.  
  2058.     lastVerb->which = NULL;
  2059.     SelectJpVerb2_Passive(NULL, lastVerb);
  2060.     lastVerb->jpProp |= JP_PROP_PASSIVE;
  2061.  
  2062.     // l'amour perdu 失われる恋愛 -> 失われた恋愛
  2063.     if(lastVerb->jpProp & JP_PROP_ACTION)
  2064.         lastVerb->frTense = (FR_TENSE)(FR_TENSE_P_PAST | FR_TENSE_PASSE);
  2065. }
  2066.  
  2067. //
  2068. // 文章 + <et> + 文章 -> 文章
  2069. //
  2070. void
  2071. CombineEtVerb(TOKEN *start)
  2072. {
  2073.     TOKEN    *p;
  2074.     TOKEN    *lastEt = NULL;
  2075.  
  2076.     for(p = start; p && p->next; p = p->next) {
  2077.         if( p->frPart == FR_PART_COMBINE_VERB
  2078.         &&  p->object2 == NULL
  2079.         && (p->next->frPart & FR_PART_VERB)
  2080.         &&  p->next->which) {
  2081.             lastEt = p;
  2082.         } else if(p->frPart == FR_PART_COMBINE_VERB
  2083.             && p->object2 == NULL) {
  2084.             lastEt = NULL;
  2085.         }
  2086.     }
  2087.  
  2088.     if(lastEt == NULL)    return;
  2089.     TOKEN    *verb = lastEt->next;
  2090.  
  2091.     if(verb->subject == NULL) {
  2092. //        verb->subject = PutNullNoun();
  2093.         verb->frPart = (FR_PART)(verb->frPart | FR_PART_SENTENCE_NO_SUBJECT);
  2094.     }
  2095.     DisconnectTOKEN(start, verb);
  2096.     lastEt->object2 = verb;
  2097.     SelectJpCombine2(lastEt, verb);
  2098. }
  2099.  
  2100. //
  2101. // <所有形容詞> + <動詞> -> <文章>
  2102. // eg) @ son arriv{ @ ce village. 彼がその村に着いたら
  2103. //
  2104. CMP_TOKEN    pat_AdjectiveVerb[] = {
  2105.     CMP_TOKEN( FR_PART_ADJECTIVE_POSSESIVE,    JP_PROP_NONE,    NULL),
  2106.     CMP_TOKEN( FR_PART_VERB_P_PAST,            JP_PROP_NONE,    IsWhichFixed),
  2107.     CMP_TOKEN( FR_PART_NONE )
  2108. };
  2109.  
  2110. void
  2111. CombineAdjectiveVerb(TOKEN *start)
  2112. {
  2113.     TOKEN    *p;
  2114.     TOKEN    *lastAdjective = NULL;
  2115.  
  2116.     for(p = start; p; p = p->next) {
  2117.         if(IsPatternMatch(pat_AdjectiveVerb, p)) {
  2118.             lastAdjective = p;
  2119.         }
  2120.     }
  2121.     if(lastAdjective) {
  2122.         CombineAdjectiveVerb(start, lastAdjective, lastAdjective->next);
  2123.     }
  2124. }
  2125.  
  2126. void
  2127. CombineAdjectiveVerb(TOKEN *start, TOKEN *adj, TOKEN *verb)
  2128. {
  2129.     ChangePossesAdjectiveToSubjectNoun(adj);
  2130.     CombineSubjectVerb(start, adj, verb);
  2131.     verb->frPart = FR_PART_SENTENCE_PPAST;
  2132.  
  2133.     // @ son arrive, 彼は到着すると -> 彼が到着すると
  2134.     adj->jpEmphasis |= JP_EMPHASIS_GA;
  2135. }
  2136.  
  2137. typedef    struct    {
  2138.     char    *adjective;
  2139.     char    *noun;
  2140. } ADJ2NOUN;
  2141.  
  2142. ADJ2NOUN AdjectiveSubjectTable[] = {
  2143.     { "mon",    "je"},
  2144.     { "ma",        "je"},
  2145.     { "mes",    "je"},
  2146.     { "ton",    "te"},
  2147.     { "ta",        "te"},
  2148.     { "tes",    "te"},
  2149.     { "son",    "il"},
  2150.     { "sa",        "il"},
  2151.     { "ses",    "il"},
  2152.     { "votre",    "vous"    },
  2153.     { "vos",    "vous"    },
  2154.     { "notre",    "nous"    },
  2155.     { "nos",    "nous"    },
  2156.     { "leur",    "ils"    },
  2157.     { "leurs",    "ils"    },
  2158.     { "",        ""        }    // End Code
  2159. };
  2160.  
  2161. void
  2162. ChangePossesAdjectiveToSubjectNoun(TOKEN *p)
  2163. {
  2164.     ADJ2NOUN    *dic = AdjectiveSubjectTable;
  2165.     while(dic->adjective[0]) {
  2166.         if(IsTokenFrench(p, dic->adjective)) {
  2167.             ChangeToPronoun(p, dic->noun);
  2168.             return;
  2169.         }
  2170.         dic++;
  2171.     }
  2172.     PrintInternalError( "Internal Error <ChangePossesAdjectiveToSubjectNoun>");
  2173. }